【Laravel 7.x】Laravelでコントローラ内で別のコントローラを呼び出す。
はじめに
・orderテーブルとorder_detailsテーブルがある
・orderとorder_detailsは1:多の関係(order_detailsにorder_idカラム)
・order_detailに送る時は、order[]の形で渡す
・createページには、orderのフィールドとorder_detailsのフィールドがあり、orderを保存するときに、order_detailsにも保存する
ということでやっていきたいと思います。
まずはシンプルにstoreメソッドでorderを保存します。
App\Http\Controllers\OrderController
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
// まずは普通の処理
$order = new Order;
$order->staff_id = $request->input('staff_id');
$order->customer_id = $request->input('customer_id');
$order->category = $request->input('category');
$order->order_date = $request->input('order_date');
// ここでorderを保存していないと、orderDetailControllerにorder_idを渡せない
$order->save();
// ここでOrderDetailControllerを使う
$save_order_detail = app()->make('App\Http\Controllers\OrderDetailController');
// OrderDetailControllerのstoreメソッドを呼び出す
// 引数として $request と先ほど生成された id を渡す
$save_order_detail->store($request, $order->id);
}
続いてorder_detail側のコントローラー
App\Http\Controllers\OrderDetailController
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request, $order_id)
{
foreach ($request->orders as $order) {
$order_detail = new OrderDetail;
// 先ほど生成された order の id
$order_detail->order_id = $order_id;
$order_detail->name = $order['name'];
$order_detail->number = $order['number'];
$order_detail->save();
}
}
こんな感じです。
app()->make('App\Http\Controllers\OrderDetailController')
これ今回実装するまで知らなかったです。
ということでメモしておきます。
補足(削除機能の実装)
このテーブルの状態で削除(destroyメソッド)を実行すると、以下のエラーが出ます。
つまり、先に外部キーとして設定しているorder_detailから削除しろよということですね。なので
public function destroy(Order $order, $id)
{
$destroy_order_detail = app()->make('App\Http\Controllers\OrderDetailController');
$destroy_order_detail->destroy($id);
$order = Order::find($id);
$order->delete();
return redirect('order');
}
まず外部キーの一致しているものを削除するコントローラを呼び出します。
そのコントローラの中身はこんな感じで実装しました。本来はEloquentを使うのが良いのかもしれませんが、SQL文で直書きしました。
public function destroy($order_id)
{
$order_detail = DB::select("SELECT od.id, od.order_id, od,name
FROM order_details od
LEFT OUTER JOIN orders o
ON od.order_id = o.id
WHERE od.order_id = $order_id");
// ある分だけ削除
foreach ($order_detail as $value) {
$value = OrderDetail::find($value->id);
$value->delete();
}
}
こんな感じです。
参考記事
この記事が気に入ったらサポートをしてみませんか?