Laravel по-русски

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

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

#1 28.03.2016 15:18:50

WebDev

Добавление в несколько таблиц

Всем привет. Такой вопрос: есть у меня 3 таблицы:
products
product_options
product_books

product_options и product_books связанны с products. В каждой таблице по много полей , эти две таблицы не связующие, а дополняющие  products.

Добавление продукта происходит так:
public function store(Request $request) {
    $store = new Product();
    $store->name = $request->name;
    ...
    $store->save();

    if ($store->id) {
        $storeOption = new ProductOptions();
        $storeOption->name = $request->optionName;
        $storeOption->save();
    }

    if ($store->id) {
        $storeBooks = new ProductBooks();
        $storeBooks->name = $request->bookName;
        $storeBooks->save();
    }
}

Если продукт создался, а продукт опция нет, то в бд останется запись продукта. Или продукт и опция создались, а продукт книга ошибка, то уже несколько записей которые не нужны. Как решить эту проблему?

#2 28.03.2016 15:25:18

Re: Добавление в несколько таблиц

Транзакции
https://laravel.com/docs/5.2/database#d … ansactions

И неплохо бы релейшены использовать
https://laravel.com/docs/5.2/eloquent-r … ted-models

Не в сети

#3 28.03.2016 15:42:48

WebDev

Re: Добавление в несколько таблиц

VitalN пишет:

Транзакции
https://laravel.com/docs/5.2/database#d … ansactions

И неплохо бы релейшены использовать
https://laravel.com/docs/5.2/eloquent-r … ted-models

Спасибо. Это для примера такой написал. Вот реальный код:

public function store(ProductStoreRequest $request)
    {
        try {
            $post = $request->all();

            $store = $this->product->store($post);

            if ($store->isSuccessful()) {
                if ($request->has('places')) {
                    $this->product->findById($store->getPayload()['model']->id)->places()
                        ->sync($request->get('places'));
                }
                if ($request->has('interests')) {
                    $this->product->findById($store->getPayload()['model']->id)->interests()
                        ->sync($request->get('interests'));
                }

                if ($request->get('dateType') == config('constant.product_options.DATE.FIXED')) {
                    $this->productOption->storeSession($data, $store->getPayload()['model']->id);
                }

                return redirect()->route('company.product.index')->withSuccess(trans('message.store.success'));
            }
                return redirect()->back()->withInput()->withError(trans('message.store.error'));
        } catch (\Exception $e) {
            return redirect()->back()->withInput()->withError(trans('message.error'));
        }
    }

Нужно везде будет писать типа так? Может есть универсальный какой метод?

public function store(ProductStoreRequest $request)
    {
        try {
            $post = $request->all();

            DB::beginTransaction();
            $store = $this->product->store($post);

            if ($store->isSuccessful()) {
                if ($request->has('places')) {
                    $this->product->findById($store->getPayload()['model']->id)->places()
                        ->sync($request->get('places'));
                }
                if ($request->has('interests')) {
                    $this->product->findById($store->getPayload()['model']->id)->interests()
                        ->sync($request->get('interests'));
                }

                if ($request->get('dateType') == config('constant.product_options.DATE.FIXED')) {
                    $this->productOption->storeSession($data, $store->getPayload()['model']->id);
                }

                DB::commit();

                return redirect()->route('company.product.index')->withSuccess(trans('message.store.success'));
            }

                DB::rollback();

                return redirect()->back()->withInput()->withError(trans('message.store.error'));
        } catch (\Exception $e) {
            DB::rollback();

            return redirect()->back()->withInput()->withError(trans('message.error'));
        }
    }

#4 28.03.2016 16:23:26

Re: Добавление в несколько таблиц

Из контроллера уберите в  метод модели
типа  $store = $this->product->storeWithOptions($post);
И жить станет веселее )

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

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

И  развернуть процесс можно, пишем опции, в конце товар и  к  нему опции аттачим.

Не в сети

#5 28.03.2016 16:27:10

Re: Добавление в несколько таблиц

Тип таблиц, кстати поддерживает транзакции? в мускуле  - innodb

Не в сети

#6 28.03.2016 16:42:10

WebDev

Re: Добавление в несколько таблиц

VitalN пишет:

Тип таблиц, кстати поддерживает транзакции? в мускуле  - innodb

Да InnoDB. Здесь как раз раздел работы с финансами.
Архитектура немного другая:
Контроллер -> Репозитории -> Трейты (если есть перекрывающие методы) -> Класс кеширования -> Модели.

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

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