Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Всем привет. Такой вопрос: есть у меня 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();
}
}
Если продукт создался, а продукт опция нет, то в бд останется запись продукта. Или продукт и опция создались, а продукт книга ошибка, то уже несколько записей которые не нужны. Как решить эту проблему?
Транзакции
https://laravel.com/docs/5.2/database#d … ansactions
И неплохо бы релейшены использовать
https://laravel.com/docs/5.2/eloquent-r … ted-models
Не в сети
Транзакции
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'));
}
}
Из контроллера уберите в метод модели
типа $store = $this->product->storeWithOptions($post);
И жить станет веселее )
Вообще транзакции обычно в финансовых приложениях чаще используют, где реально труба, если что-то не запишется.
Если что-то попроще, хватает обычно валидации всего что должно записаться, затем запись кучкой.
И развернуть процесс можно, пишем опции, в конце товар и к нему опции аттачим.
Не в сети
Тип таблиц, кстати поддерживает транзакции? в мускуле - innodb
Не в сети
Тип таблиц, кстати поддерживает транзакции? в мускуле - innodb
Да InnoDB. Здесь как раз раздел работы с финансами.
Архитектура немного другая:
Контроллер -> Репозитории -> Трейты (если есть перекрывающие методы) -> Класс кеширования -> Модели.
Довольно сложное приложение выходит, но очень удобно работать имея несколько прослоек до модели, через которые нужно менять много данных.
Страницы 1