Laravel Передача моделей разных классов в один метод контроллера

  • Автор темы Автор темы MaksM
  • Дата начала Дата начала

MaksM

Новичок
Можно ли как-то передавать в метод контроллера модели разных классов? Никак не могу найти решение. Вот простейший пример есть метод
PHP:
class MyController extends Controller
{
    public function updateName(Request $request, $model){
        $model->update($request->all());
    }
}

Суть в том, что я хочу обновлять поле "name" в разных моделях. Т.е. к примеру есть модели cats, dogs, и т.д. у всех есть возможность поменять имя и это одинаковый по сути код.
Как я понимаю роут типа
PHP:
Route::post('cats/{model}/name', 'MyController@updateName');
Route::post('dogs/{model}/name', 'MyController@updateName');
{model} - это id какой-то записи, у которой надо обновить name
не прокатит т.к. в параметр $model метода контроллера будет просто передан id-шник, а не объект.
Можно конечно сделать так:
PHP:
Route::post('cats/{model}/name', function(App\Cat $model){
// но как тут вызвать метод контроллера?
});
 
Обоснуйте хоть )), ну и решение конечно тоже было бы здорово увидеть, а нужно так делать или нет, это мне решать (после прочтенного обоснования)
 
@MaksM, начни с внятного описания проблемы.

Сейчас я скажу только то, что у тебя будет 1 post запрос, и по идеалогии он должен обновлять одну сущность, к которой и относится - профиль кота или собаки.

Как я вижу логику:
PHP:
Route::post('cats/{id}/update', 'Cats@update')->where(...);
Route::post('dogs/{id}/update', 'Dogs@update')->where(...);

Сейчас придет @Adelf и даст по ушам, но пофик)))
 
Обоснуйте хоть )), ну и решение конечно тоже было бы здорово увидеть, а нужно так делать или нет, это мне решать (после прочтенного обоснования)
Если тебе пофиг на то, что именно ты «обновляешь», то просто дай доступ клиенту напрямую к базе данных, какую роль выполняешь ты?
 
@MaksM, начни с описания проблемы, а не хотелок. Так яснее?
 
Как я вижу логику:
PHP:
Route::post('cats/{id}/update', 'Cats@update')->where(...);
Route::post('dogs/{id}/update', 'Dogs@update')->where(...);
Вот это, подразумевает ,что я обновляю данные в целом. Представь, что там еще десяток полей и мне не надо их ни менять, ни проверять (раз менять я их не собираюсь), а я хочу обновить только имя и более того, я знаю, что это имя я буду обновлять еще у многих разных моделей.
 
@MaksM, ты если будешь потом обновлять еще какое-то одно поле, тоже будешь городить новый контроллер?
Или все же напишешь логику так, что обновляться будут только те поля, которые переданы?

И при чем тут "это имя я буду обновлять еще у многих разных моделей"? Обычно один post запрос обвновляет одну модель (и связанные с ней данные, подчиненные модели). У тебя как-то по другому, один запрос обновляет всех котов-собак?
 
Мне нужно поменять только имя, не передавая туда другие, возможно обязательные поля, например для быстрого редактирования. Через ajax я создаю post запрос куда передаю только имя и id записи у которой это имя надо обновить. И для кошек, собак, хомяков, людей, городов, рек и еще "триллиона" моделей есть возможность быстро отредактировать имя. Это по сути один и тот же код (проверка наличия переданного имени, правильность его написания, ... еще что-то). Не хочется писать триллион одинаковых методов в каждом контроллере. Можно было бы написать один контроллер с таким методом и туда передавать name и модель у которой этот name нужно обновить. Теперь понятно?
 
Или все же напишешь логику так, что обновляться будут только те поля, которые переданы?
Это тоже хороший вариант решения, но другой задачи )) Это, как ты сказал, если потом я буду обновлять еще какое-то одно поле, а вот если только одно то хотелось бы конечно снизить писанину до минимума. Да и для общего развития неплохо бы узнать, возможно ли как-то передать в контроллер разные модели )
 
@MaksM, ты никак не уйдешь от того, чтобы проверить наличие передаваемой в post переменной с именем модельки

PHP:
Route::post('entity/{model}/{id}/update', 'Generic@entityNameUpdate')->where('model', '[a-z]+')->where('id', '[0-9]+');

А внутри контроллера уже решаешь что сделать

PHP:
public function entityNameUpdate(Request $request, int $id, string $type){
    if(class_exists($type)){
        $result = app($type)->updateName($id, $request->get('name'));
    } else {
        throw new ApplicationUnexpectedValueException('...');
    }
    
    if($result){
        #
    }
}

Ясен пень, что тут надо еще кучу проверок и вообще так делать не надо
 
Да, согласен, это вообще не вариант.
Вообщем, печально, но видимо для этой цели все же правильным будет писать метод в каждом контроллере и тогда уж не для каждого поля, а как ты предлагал, для переданных. Спасибо за потраченное время )
 
Задача решаема:
1. В запросе можно фильтровать поля (убрать не подходящие под модель через except).
2. Возможна валидация поля только, если оно есть в запросе (sometimes).
3. Обновлять можно только присутствующие в запросе поля (запрос вернёт только имеющиеся в нём поля).
 
Сверху