#laravel #controller #request
#laravel #контроллер #запрос
Вопрос:
У меня есть проект с несколькими контроллерами и моделями. Например, в таблице products есть «дочерняя» таблица (подробная информация о продукте) с именем «producto_material».
Во внешнем интерфейсе пользователь создает новый продукт, но у этого продукта должна быть хотя бы одна деталь. Когда пользователь нажимает «Создать продукт», запрос отправляется с информацией о продукте (products) и подробной информацией о продукте (producto_material).
На данный момент у меня есть следующая структура:
- Контроллеры (ProductoController, ProductoMaterialController)
- Модели (ProductoModel, ProductoMaterialModel)
Мне нравится, чтобы каждый контроллер выполнял вашу собственную проверку, но запрос отправляется на ProductController.
Веб-маршруты:
Route::resource('products', 'ProductoController');
Route::get('duplicar/{param?}', 'ProductoExtController@duplicar');
Route::post('mostrarProductos', 'ProductoExtController@mostrarProductos');
Route::post('guardarValoresEditados', 'ProductoExtController@guardarValoresEditados');
Route::get('imprimirListadoPrecios', 'ProductoExtController@imprimirListadoPrecios');
Route::post('mostrarProductosStickers', 'ProductoExtController@mostrarProductosStickers');
Route::post('imprimirStickers','ProductoExtController@imprimirStickers');
Контроллер продукта:
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppModelosProductsModel;
use AppModelosProductoMaterialModel;
use IlluminateSupportFacadesValidator;
use IlluminateSupportArr;
use AppHttpRequestsProductoValidationRules;
use CarbonCarbon;
use IlluminateSupportFacadesDB;
use IlluminateSupportFacadesAuth;
class ProductoController extends Controller
{
protected $proMaterialesProducto;
public function __construct(ProductoMaterialController $pMaterialesProducto)
{
$this->proMaterialesProducto = $pMaterialesProducto;
}
/**
* Display a listing of the resource.
*
* @return IlluminateHttpResponse
*/
public function index()
{
if (Gate::allows('isAdmin') || Gate::allows('isUser')){
return ProductsModel::latest()
->orderBy('created_at','desc')
->paginate(10);
}
}
/**
* Show the form for creating a new resource.
*
* @return IlluminateHttpResponse
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param IlluminateHttpRequest $request
* @return IlluminateHttpResponse
*/
public function store(ProductoValidationRules $request)
{
$vIntIdProducto = 0;
try {
$validated = $request->validated();
DB::beginTransaction();
$vIntIdProducto = ProductsModel::insertGetId([
'f014_nombre' => $request['nombre'],
'f014_precio_basico'=> $request['vlrBasico'],
'f014_precio_premium' => $request['vlrPelete'],
'f014_categoria_id' => $request['categoria'],
'f014_id_coleccion'=> $request['coleccion'],
'created_at'=> Carbon::now()->toDateTimeString(),
'f014_creado_por'=> Auth::id(),
]);
foreach (Arr::get($request,'colores') as $key => $color) {
ProductoMaterialModel::insert([
'f019_producto_id' => $vIntIdProducto,
'f019_crosta_id'=> Arr::get($color,'crosta.valor'),
'f019_id_folia1' => Arr::get($color,'folia1.valor'),
'f019_id_folia2' => Arr::get($color,'folia2.valor'),
'f019_id_folia3'=> Arr::get($color,'folia3.valor'),
'f019_color'=> Arr::get($color,'color'),
'f019_creado_por'=> Auth::id(),
]);
}
DB::commit();
return response()
->json(['status' => true]);
} catch (Throwable $th) {
DB::rollBack();
return response()
->json([
'status' => false,
'message' => 'Fallo la creación del producto '.$th->getMessage()
]);
}
}
/**
* Display the specified resource.
*
* @param int $id
* @return IlluminateHttpResponse
*/
public function show($id)
{
$vProductsModel = ProductsModel::with(
'MaterialesCombinaciones.Crostas',
'MaterialesCombinaciones.Folia1',
'MaterialesCombinaciones.Folia2',
'MaterialesCombinaciones.Folia3'
)
->where('f014_id',$id)
->get();
return response()
->json($vProductsModel);
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return IlluminateHttpResponse
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param IlluminateHttpRequest $request
* @param int $id
* @return IlluminateHttpResponse
*/
public function update(Request $request, $id)
{
$vProductos = null;
try {
DB::beginTransaction();
$vProductos = ProductsModel::find($id);
$vProductos->f014_precio_basico = $request['vlrBasico'];
$vProductos->f014_precio_premium = $request['vlrPelete'];
$vProductos->f014_modificado_por = Auth::id();
$vProductos->save();
foreach (Arr::get($request,'colores') as $key => $color) {
ProductoMaterialModel::updateOrCreate(
[
'f019_producto_id' => $id,
'f019_crosta_id' => Arr::get($color,'crosta.valor'),
'f019_color'=>Arr::get($color,'color')
],
[
'f019_id_folia1' => Arr::get($color,'folia1.valor'),
'f019_id_folia2' => Arr::get($color,'folia2.valor'),
'f019_modificado_por'=>Auth::id()
]
);
}
DB::commit();
return response()
->json(['status' => true]);
} catch (Throwable $th) {
DB::rollBack();
return response()
->json([
'status' => false,
'message' => 'Fallo la actualización del producto '.$th->getMessage()
]);
}
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return IlluminateHttpResponse
*/
public function destroy($id)
{
ProductsModel::destroy($id);
}
}
Я думаю, что это неправильно:
$vIntIdProducto = ProductsModel::insertGetId([
'f014_nombre' => $request['nombre'],
'f014_precio_basico'=> $request['vlrBasico'],
'f014_precio_premium' => $request['vlrPelete'],
'f014_categoria_id' => $request['categoria'],
'f014_id_coleccion'=> $request['coleccion'],
'created_at'=> Carbon::now()->toDateTimeString(),
'f014_creado_por'=> Auth::id(),
]);
foreach (Arr::get($request,'colores') as $key => $color) {
ProductoMaterialModel::insert([
'f019_producto_id' => $vIntIdProducto,
'f019_crosta_id'=> Arr::get($color,'crosta.valor'),
'f019_id_folia1' => Arr::get($color,'folia1.valor'),
'f019_id_folia2' => Arr::get($color,'folia2.valor'),
'f019_id_folia3'=> Arr::get($color,'folia3.valor'),
'f019_color'=> Arr::get($color,'color'),
'f019_creado_por'=> Auth::id(),
]);
}
Комментарии:
1. Если пользователь НЕ МОЖЕТ создать ‘ProductoMaterial’ без ‘Producto’, то вам не нужен ProductoMaterialController… Вы просто устанавливаете связь Producto-> hasMany(ProductoMaterial::class), и когда вы сохраняете Producto, вы создаете с ним ProductoMaterial
2. Нет ничего плохого в создании записей Parent Children в одних и тех же контроллерах. Я бы сказал, что это должно быть правильным способом. Единственное, если вы используете движок InnoDB или базу данных, которые поддерживают транзакции, то вам следует использовать ваши вставки в транзакцию DB, чтобы гарантировать, что родительский элемент не сохранит дочерний элемент. Используйте
DB::beginTransaction();
перед вставками,DB::commit();
после иDB::rollback();
при перехватывании исключения.