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

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

Новичок
Обоснуйте хоть )), ну и решение конечно тоже было бы здорово увидеть, а нужно так делать или нет, это мне решать (после прочтенного обоснования)
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@MaksM, начни с внятного описания проблемы.

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

Как я вижу логику:
PHP:
Route::post('cats/{id}/update', 'Cats@update')->where(...);
Route::post('dogs/{id}/update', 'Dogs@update')->where(...);
Сейчас придет @Adelf и даст по ушам, но пофик)))
 

Вурдалак

Продвинутый новичок
Обоснуйте хоть )), ну и решение конечно тоже было бы здорово увидеть, а нужно так делать или нет, это мне решать (после прочтенного обоснования)
Если тебе пофиг на то, что именно ты «обновляешь», то просто дай доступ клиенту напрямую к базе данных, какую роль выполняешь ты?
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@MaksM, начни с описания проблемы, а не хотелок. Так яснее?
 

MaksM

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

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@MaksM, ты если будешь потом обновлять еще какое-то одно поле, тоже будешь городить новый контроллер?
Или все же напишешь логику так, что обновляться будут только те поля, которые переданы?

И при чем тут "это имя я буду обновлять еще у многих разных моделей"? Обычно один post запрос обвновляет одну модель (и связанные с ней данные, подчиненные модели). У тебя как-то по другому, один запрос обновляет всех котов-собак?
 

MaksM

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

MaksM

Новичок
Или все же напишешь логику так, что обновляться будут только те поля, которые переданы?
Это тоже хороший вариант решения, но другой задачи )) Это, как ты сказал, если потом я буду обновлять еще какое-то одно поле, а вот если только одно то хотелось бы конечно снизить писанину до минимума. Да и для общего развития неплохо бы узнать, возможно ли как-то передать в контроллер разные модели )
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
@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){
        #
    }
}
Ясен пень, что тут надо еще кучу проверок и вообще так делать не надо
 

MaksM

Новичок
Да, согласен, это вообще не вариант.
Вообщем, печально, но видимо для этой цели все же правильным будет писать метод в каждом контроллере и тогда уж не для каждого поля, а как ты предлагал, для переданных. Спасибо за потраченное время )
 

jonjonson

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