Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 02.11.2017 14:04:41

Перенести логику из контроллера в модель

AlexeyMezenin, Спасибо за ответ.
Но есть еще 1 вопрос. С запросом на получение данных все понятно, переносим его в модель делаем метод типо getAll а в контроллере вызываем этот метод.
А как быть с запросом типа insert?
Ну к примеру я в методе store сохраняю данные в базу

PHP
/**
     * Update the specified resource in storage.
     *
     * @param  BackendProductRequest  $request
     * @param  Product $product
     * @return \Illuminate\Http\Response
     */
    
public function update(BackendProductRequest $requestProduct $product)
    {
        try
        {
            
$product->update([
                
'meta_title' => $request->meta_title,
                
'meta_description' => $request->meta_description,
                
'meta_keywords' => $request->meta_keywords,
                
'name' => $request->name,
                
'slug' => $request->slug,
                
'reference' => $request->reference,
                
'ean13' => $request->ean13,
                
'upc' => $request->upc,
                
'isbn' => $request->isbn,
                
'short_description' => $request->short_description,
                
'full_description' => $request->full_description,
                
'image' => $request->image FileManagerService::make($request->slug$request->image'upload/products/main')->upload()->getLink() : Null,
                
'is_active' => $request->is_active 0,
                
'sold_out' => $request->sold_out 0,
                
'quantity' => $request->quantity $request->quantity 0,
                
'minimum_quantity' => $request->minimum_quantity $request->minimum_quantity 0,
                
'wholesale_price' => $request->wholesale_price,
                
'price' => $request->price,
                
'manufacturer_id' => $request->manufacturer,
                
'category_id' => $request->category_default,
                
'lang_id' => $request->lang $request->lang 1,
                
'width' => $request->width $request->width 0,
                
'height' => $request->height $request->height 0,
                
'depth' => $request->depth $request->depth 0,
                
'weight' => $request->weight $request->weight 0,
            ]);

            
// Here we remove id of empty product
            // cause user populate product fields
            
$request->user()->draft()->where('product_id'$product->id)->delete();

            if(
$request->product_carrier)
                
$product->carriers()->sync($request->product_carrier);

            if(
$request->category)
                
$product->categories()->sync($request->category);

            if(
$request->product_feature)
                
$product->features()->sync($this->cleanArr($request->product_feature));

            if(
$request->input('save_stay'))
                return 
redirect()->route('products.edit', ['id' => $product->id])->with('success''Successfully updated');

            return 
redirect()->route('products.index')->with('success''Successfully updated');
        }
        catch (\
Throwable $t)
        {
            return 
redirect()->back()->with(['error' => 'An error occurred while updating the product''error_message' => $t->getMessage()])->withInput($request->input());
        }
    }

Как укоротить и перенести в модель этот метод? Ведь нельзя просто сделать create($request->only('...')) так как там идут проверки.

Не в сети

#2 02.11.2017 14:56:29

Re: Перенести логику из контроллера в модель

Во-первых, нужно избавиться от всех этих 'minimum_quantity' => $request->minimum_quantity ? $request->minimum_quantity : 0. Используй ->default(0) в миграциях, чтобы задать значение по умолчанию.

Зачем ты используешь try catch? Разве данные могут не обновиться? Нужно использовать железную валидацию для входных данных.

Контроллер мог бы выглядеть как-то так:

public function update(BackendProductRequest $request, Product $product)
{
    $image = $this->fileService->handleImage($request->image);

    $product->updateAndSync(array_merge($request->all(), compact('image')));

    return redirect()->route('products.index')->with('success', __('app.updated'));
}

Вместо простыни в updateAndSync используй массовое заполнение.

sync в том же updateAndSync делаешь, потому что они относятся к продукту. А вот $request->user()->draft()->where('product_id', $product->id)->delete() надо бы переписать (ведь наверняка есть и обратная связь между product и draft).

Изменено AlexeyMezenin (02.11.2017 14:58:39)

Не в сети

#3 02.11.2017 15:26:35

Re: Перенести логику из контроллера в модель

'minimum_quantity' => $request->minimum_quantity ? $request->minimum_quantity : 0

Не забывайте про сокращенные операторы ?: и ??

$request->minimum_quantity ?: 0

.

Разве данные могут не обновиться? Нужно использовать железную валидацию для входных данных.

Валидация не поможет - во-первых, никто не гарантирует точную синхронизацию структуры БД и кода (банально: увеличили лимит поля, но забыли обновить валидатор, или наоборот), а, во-вторых, ошибки БД могут возникнуть и сами по себе (пропала связь до БД, если она на другом хосте, таймаут транзакции и т.д.). Другое дело, что блок try..catch больно длинный, но это отдельный вопрос.

Не в сети

#4 02.11.2017 15:35:43

Re: Перенести логику из контроллера в модель

Все-таки данные по дефолту лучше в таблице устанавливать вместо их назначения вручную каждый раз при работе с этой таблицей.

На счет try catch, в большинстве случаев я бы предпочел увидеть Whoops, ибо такое случается один раз в xxx. Но если нужно вывести красивое сообщение об ошибке, тогда да.

Не в сети

#5 02.11.2017 16:15:29

htclog81
Откуда: Москва
Сообщений: 192
Сайт

Re: Перенести логику из контроллера в модель

Вроде бы можно юзеру показывать на боевом сервере что то типа одинаковой 500 страницы на случай не пойманного исключения?

Не в сети

#6 04.11.2017 12:50:31

Re: Перенести логику из контроллера в модель

  1. Используй —>default(0) в миграциях

так и есть, по ривычке проверяю))

  1. Зачем ты используешь try catch? Разве данные могут не обновиться? Нужно использовать железную валидацию для входных данных.

не соответствие имени инпута к имени столбца в бд, и крах.

  1. ведь наверняка есть и обратная связь между product и draft

да, есть. Спасибо. Буду все в модели теперь переносить)

Не в сети

Подвал раздела