Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Всем привет!
Пишу сайт недвижимости, нужно работать с множеством разных объектов недвижимости, которые частично отличаются друг от друга.
Решил использовать фабрику при создании объектов, сделать общий интерфейс и разбить на классы. Уперся я в то, что для сохранения в БД, объект должен быть экземпляром EstateObject
...
class EstateObject extends Model
{
protected $table = 'objects';
public function complex()
{
return $this->belongsTo('App\Complex', 'complex_id');
}
...
Но при создании нового объекта, например FlatObject, не могу уйти дальше. Как я понял, нужно как-то объединить модели в коллекцию, чтобы юзать общую базу `objects`. Но технически ничего не выходит. Подскажите, куда копать и вообще верно ли я мыслю? ))
p.s.: читал у какого Британца про Recast моделей, но до конца не въехал (
<?php
namespace App\Http\Controllers\Interfaces;
interface EstateObjectInterface
{
public function setObjectType(string $objectType);
public function setDealType(string $dealType);
public function setName(string $objectType, int $roomsCount);
public function setPrice(int $price);
}
<?php
namespace App\Http\Controllers\Admin\Objects;
use App\Http\Controllers\Interfaces\EstateObjectInterface;
class ResidentialFactory extends EstateObjectFactoryMethod
{
protected function createObject(string $type): EstateObjectInterface
{
switch ($type) {
case parent::FLAT:
return new FlatObject();
case parent::ROOM:
return new RoomObject();
default:
throw new \InvalidArgumentException("$type is not a valid object");
}
}
}
<?php
namespace App\Http\Controllers\Admin\Objects;
use App\EstateObject;
use App\Http\Controllers\Interfaces\EstateObjectInterface;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
abstract class EstateObjectFactoryMethod extends Controller
{
const FLAT = 'квартира';
const ROOM = 'комната';
abstract protected function createObject(string $type): EstateObjectInterface;
public function create(Request $request): EstateObjectInterface
{
$object = $this->createObject($request['object_type']);
$object->setObjectType($request['object_type']);
$object->setDealType($request['deal_type']);
$object->setName($request['object_type'], $request['rooms_count']);
$object->setPrice($request['price']);
$this->saveInDB($object); //вот здесь хочется сохранить объект в БД
return $object;
}
Вот так я планировал создать-сохранить, а затем вернуть сохраненный объект фронту
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Admin\Objects\ResidentialFactory;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class ObjectController extends Controller
{
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$factory = new ResidentialFactory();
$object = $factory->create($request);
return response()->json($object, 200, [], JSON_UNESCAPED_UNICODE);
}
}
Вот часть одного из видов объекта
<?php
namespace App\Http\Controllers\Admin\Objects;
use App\EstateObject;
use App\Http\Controllers\Interfaces\EstateObjectInterface;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class FlatObject implements EstateObjectInterface
{
private $objectType;
private $dealType;
private $name;
private $price;
public function setObjectType(string $objectType)
{
$this->objectType = $objectType;
}
public function setDealType(string $dealType)
{
$this->dealType = $dealType;
}
public function setName(string $objectType, int $roomsCount = null)
{
$this->name = $this->getNameByParams($objectType, $roomsCount);
}
Всем привет!
Подскажите, правильный выбрал подход?
В форме есть два поля: "name", "slug". Нужно, чтобы пользователь видел сгенерированный slug и мог его изменить.
При смене названия, аяксом отправляю запрос:
$('[name="name"]').change(function() {
createLink($(this), $('[name="slug"]'));
});
function createLink(src, dst) {
$.ajax({
method: 'get',
url: '/generate_link/' + src.val(),
data: {
'_token': $('[name="_token"]').val()
},
success: function(data) { dst.val(data); }
});
}
В app я создал папку Helpers и в ней файл TextHelper.php
...
namespace App\Helpers;
class TextHelper
{
public function generateLink($source)
{
$generatedLink = $this->toTranslit($source);
return response()->json($generatedLink);
}
protected function toTranslit($str)
...
Создал HelperServiceProvider.php, зарегистрировал в нем мой хелпер
...
public function register()
{
$this->app->bind('textHelper', function() {
return new TextHelper();
});
}
...
И вот такое я сделал в роутах:
Route::get('/generate_link/{source}', function($source) {
$slug = \Illuminate\Support\Facades\TextHelper::generateLink($source);
return $slug;
});
Стилистически/технически это верно? Или можно более "благородно" ?
На js всё можно сделать гораздо проще.
Благодарю, теперь можно будет уменьшить код
у тебя не $request['name'] а $request['name ']. пробел в ключе лишний
Спасибо! Правда вечером знакомый зашел, увидел пробел )
Всем привет!
В метод update класса FilmController приходит пустой $request (var_dump($request['name'] отдает null),
хотя fd.get('name'), перед отправкой ajax, выдает значение имени.
Даже пробовал руками присваивать переменную:
fd.append('name', 'boo');
Все равно пусто
Подскажите, где туплю?
Есть форма:
<form name="editFilmForm" id="editFilmForm" method="post">
<input type="hidden" name="_method" value="put">
<div class="form-group">
<label for="name">Name</label>
<input type="text" name="name" class="form-control" id="name" value="{{$film->name}}" required>
</div>
<input type="hidden" name="_token" value="{{ Session::token() }}">
<input type="hidden" name="filmId" value="{{ $film->id }}">
<button type="submit" class="btn btn-default editFilmSubmit">Submit</button>
</form>
Route:
Route::resource('films', 'FilmController');
Controller:
class FilmController extends Controller
{
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
var_dump($request['name ']);die;
}
}
JS:
$('[name="editFilmForm"]').on('submit', function (e) {
var fd= new FormData(this);
var url = '/films/' + $('[name="filmId"]').val();
var token = $('[name="_token"]').val();
fd.append('token', token);
fd.append('_method', 'put');
e.preventDefault();
// команда ниже успешно отдает значение имени
// console.log(fd.get('name'));return false;
$.ajax({
type: 'post',
url: url,
data: fd,
mimeType: "multipart/form-data",
contentType: false,
cache: false,
processData: false,
success: function (data) {
console.log(data);return false;
},
error: function (data) {
console.log(data['responseText']);return false;
}
});
});