Laravelの書籍では、「親・子」のリレーションに関する記載はよく見られますが、「親・子・孫」のリレーションに関しては見たことがありません。
下記のような構造のモデルがあったとします。
会員(users)が注文(orders)して、複数の注文詳細(order_details)があります。
usersとordersとorder_detailsの関係は、
- users → orders hasMany
- orders → order_details hasMany
となっていて、「親・子・孫」の関係になっています。
各モデルには下記のようにリレーションを書きました。
/**
* Orderとのリレーション
*/
public function order()
{
return $this->hasMany('App\Order');
}
/**
* Userとのリレーション
*/
public function user()
{
return $this->belongsTo('App\User');
}
/**
* OrderDetailとのリレーション
*/
public function orderDetail()
{
return $this->hasMany('App\OrderDetail');
}
/**
* Orderとのリレーション
*/
public function order()
{
return $this->belongsTo('App\Order');
}
コントローラで下記のように記述しましたが、エラーになりました。
public function index()
{
$items = Auth::user()->order()->orderDetail;
}
Laravalのドキュメントを眺めたところ、「hasMenyThrough」というリレーションを使いなさい、と書いてありました。
6.x Eloquent:リレーション Laravel
Userモデルに下記を追記します。
/**
* OrderDetailとのリレーション
*/
public function orderDetail()
{
return $this->hasManyThrough('App\OrderDetail', 'App\Order');
}
コントローラで下記のように記述すると、データが取得できました。
public function index()
{
$items = Auth::user()->orderDetail;
}
ただ、この方法だと「orderDetail」モデルの情報しか取得できないので、下記のように書いてみました。
public function index()
{
$items = Auth::user()->with('order')->with('orderDetail')->get();
}
このようにデータが取得できました。
しかし、この方法だとOrderとOrderDetail(子と孫)がオブジェクトの中で並列の関係になってしまっています。
あれこれ試してみましたがうまく行かず、結局この方法が一番いいのかも?と思いました。
public function index()
{
$items = Order::with('orderDetail')
->where('orders.user_id', '=', Auth::user()->id)
->get();
}
ちゃんとOrderとOrderDetailが「子と孫」の関係になっています。