Неправильно ли использовать тот же метод для SAVE и UPDATE?

Я использую laravel, но это не важно, когда вы создаете контроллер с помощью инструмента командной строки laravel, он помещает 4 функции по умолчанию для создания и обновления.

create и store для save

edit и update для update !

Это то, что предлагает laravel для контроллера Shop.

 class ShopController extends Controller { public function create() { // return create view } public function store(Request $request) { // save a shop } public function edit($id) { // find a shop , return edit view } public function update(Request $request, $id) { // find the shop with id , update the shop } } 

Но мне нравится использовать те же методы для отображения вида и сохранения / обновления моей строки и избегать написания большого количества дополнительного кода.

 class ShopController extends Controller { public function create($id = 0) { return view('shop-create' , ['edit'=> Shop::find($id)]); } public function store(Request $request , $id = 0 ) { $whitelist = [ 'title'=>'required', 'phone'=>'present|numeric' , 'address'=>'present' , ]; $this->validate($request, $whitelist ); $shop = Shop::findOrNew($id) ; // find a shop with given id or create a new shop instance foreach($whitelist as $k=>$v) $shop->$k = $request[$k]; $shop->save(); } } 

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

Ничего плохого, но вам будет сложнее понять, ИМХО.

например :

  • Что делает этот метод? Он называется create , но он также редактируется?
  • Вид называется shop-create но он также редактирует?
  • Передача параметра 0 по умолчанию для id и попытка find его каждый раз не требуется.
 public function create($id = 0) { return view('shop-create' , ['edit'=> Shop::find($id)]); } 

Несмотря на то, что вы думаете, что упрощаете свой код, вы становитесь более сложным, так как вы выполняете принцип Single Responsability от SOLID .

Проще всего понять, есть ли у вас что-то вроде предложения Laravel.

Также вы придерживаетесь очень распространенного шаблона, который любой разработчик Laravel поймет, поэтому вы можете нанять кого-то, кто позаботится о вашем коде, и не беспокойтесь, если он поймет.

Нет ничего плохого в том, чтобы делать это по-своему. «Laravel», о котором вы говорите, – это когда вы создаете контроллер ресурсов Restful и просто один из способов его решения.

Я предполагаю, что эти методы контроллера были выбраны, потому что они хорошо сочетаются с контроллером «успокоительного» типа. Если бы вы строили истинный отдых api, то, как вы это делаете, он становится намного более строгим с точки зрения стандартов (не навязывается laravel, а лучше подходит к larvel).

Если вы не создаете публичную обращенную api или что-то, что будет потребляться внешними объектами, тогда я говорю, что проектируйте свои контроллеры, которые лучше всего подходят для вас и вашей команды

Использование одной и той же функции для save () и update () – хорошая идея, но в то же время она увеличит сложность. Один момент: если в будущем вы хотите изменить все, что вам нужно, чтобы изменить его только в одном месте. Но в то же время вам нужно проявлять особую осторожность.

Поскольку ваша функция должна быть более динамичной.

1) Несколько манипуляций с документами : вам может потребоваться обновить несколько ресурсов одновременно, поэтому ваша функция должна быть достаточно гибкой, чтобы вставлять / обновлять одно / несколько значений одной и той же функцией. Значение, один запрос должен быть запущен для нескольких записей в обоих случаях.

2) Проверка, если значение уже существует : когда вы собираетесь проверить некоторую проверку … в случае вставки вам нужно только проверить, существует ли значение в db или нет, когда в случае обновления вам нужно проверить с исключением текущего идентификатора, например

для вставки

  $this->validate($request, [ 'email' => 'required|string|email|unique:tablename,email' ]); 

для случая обновления

  $this->validate($request, [ 'email' => 'required|string|email|unique:tablename,email,'.$id.',id' ]); 

И, наконец, очень маленькая точка, но нужно учитывать ..

3) Сообщение о успехе: во время ввода сообщения должно быть «добавлено успешно» и во время обновления. Запись «обновлена ​​успешно».

Я использовал этот метод в последнем моем проекте, мы назвали функцию store() и update() manage() вместо функции manage() и имели getManage() которые использовали бы тот же вид для создания и редактирования. Мне очень понравился этот метод, но натолкнулся на несколько вещей, которые стоит отметить. К сожалению, противятся профи, если вам приходится сталкиваться с этими проблемами 🙁

Плюсы:

  • Меньший код. У вас больше нет дубликатов строк в функции store() и update() .
  • Быстрее повторное использование с базовыми моделями – ctrl+c ctrl+v ctrl+f ctrl+r если вы знаете, что я имею в виду.
  • Легче добавлять / изменять входные значения. Дополнительное значение не означает необходимость менять store() и update() чтобы убедиться, что они оба используют дополнительный ввод.
  • Одна функция, чтобы управлять ими всеми – пока вы ничего не делаете, вы можете даже определить одну функцию для всего. Нужно что-то изменить? У вас есть одна функция, не беспокойтесь.

Минусы:

  • Код сложнее понять для других (или старше вас). Если кто-то не знаком с этим методом или не использовал его через некоторое время, понимание того, что происходит внутри вашей функции, немного сложнее, чем наличие двух отдельных.
  • Валидация – это неприятность. Как указано в этом ответе, проверка может отличаться для создания и обновления. Это означает, что вам иногда приходится писать две проверки, которые в конечном итоге приведут к беспорядочному коду, и мы этого не хотим!
  • Вставка значений была не такой классной, как я думал. Если вы хотите использовать один и тот же предопределенный массив для создания или обновления, вы можете столкнуться с проблемой необходимости вставлять значения в create, но никогда не хотите их обновлять. Это в конечном итоге привело либо к уродливым операторам, либо к двум предопределенным массивам.

В конце концов, это зависит от того, что вы собираетесь делать и что вы хотите сделать. Если у вас есть базовый веб-сайт, который будет управлять сообщениями в блогах и страницами, то не беспокойтесь о функции shared store() и update() . Тем не менее, если вы создаете огромную CMS со многими моделями, отношениями и разными значениями ввода и обновления, которые могут означать различную проверку, я бы пошел с тем, что рекомендует Laravel. В долгосрочной перспективе было бы намного проще поддерживать, и вам не придется иметь дело с головными болями, хакерскими исправлениями и нечистым кодом.

Независимо от того, что вы делаете, не делайте оба в разных контроллерах! Это было бы странно.

Кстати, если вам интересно, какой проект у меня был – это была огромная CMS. Поэтому, хотя это было очень полезно и легко в некоторых случаях, это, к сожалению, не стоило того.

Ничего плохого, но в этом случае вы должны поддерживать правильные комментарии, которые указывают, что ваша функция выполняет добавление / редактирование, и для этого вы используете некоторую переменную типа $ id или что-то еще. Если он доступен, вы можете обновить запись, иначе вставьте ее.

Так я обычно это делаю, таким образом, вы все еще можете иметь другую проверку, используя запросы, и все еще ясно (imo), что делают функции.

 public function store(AdminPartnerRequest $request) { return $this->handleCreateOrUpdate($request); } public function update(AdminPartnerRequest $request, $id) { return $this->handleCreateOrUpdate($request,true, $id); } private function handleCreateOrUpdate($request, $edit = false, $id = null) { if ($edit){ $partner = Partner::find($id); } else{ $partner = new Partner(); } $partner->name = $request->input('name'); $partner->picture = $request->input('image'); $partner->save(); return \Redirect::route('admin.partners.index'); } - public function store(AdminPartnerRequest $request) { return $this->handleCreateOrUpdate($request); } public function update(AdminPartnerRequest $request, $id) { return $this->handleCreateOrUpdate($request,true, $id); } private function handleCreateOrUpdate($request, $edit = false, $id = null) { if ($edit){ $partner = Partner::find($id); } else{ $partner = new Partner(); } $partner->name = $request->input('name'); $partner->picture = $request->input('image'); $partner->save(); return \Redirect::route('admin.partners.index'); } 

Малый проект, делай все, что хочешь. Большие с другими разработчиками, следуйте соглашениям.

Соглашения о кодировании представляют собой набор руководств для конкретного языка программирования, которые рекомендуют стиль, методы и методы программирования для каждого аспекта программы, написанной на этом языке. Эти соглашения обычно охватывают организацию файлов, отступы, комментарии, декларации, заявления, пробелы, соглашения об именах, методы программирования, принципы программирования, эмпирические правила программирования, лучшие архитектурные рекомендации и т. Д. Это рекомендации по качеству программного обеспечения. Программистам настоятельно рекомендуется следовать этим рекомендациям, чтобы улучшить читаемость исходного кода и упростить обслуживание программного обеспечения. Соглашения о кодировании применимы только к человеческим сопровождениям и экспертам-сверстникам программного проекта. Соглашения могут быть формализованы в документированном наборе правил, который следует всей команде или компании, или может быть столь же неформальной, как привычная практика кодирования личности. Компиляторы не применяют соглашения о кодировании. – https://en.wikipedia.org/wiki/Coding_conventions