【Laravel】Eloquentリレーションに固定の条件で絞り込む

こんにちは。今回はEloquentのリレーションに関する話題です。

リレーションは通常、モデルの項目同士をキーにします。しかしたまに項目以外の固定の条件を追加したい時があります。一言で説明するのが難しいので、例を挙げます。

ショッピングサイトで特定のユーザーが購入した商品の一覧を取得したい場合があります。この場合ユーザー(User)と販売(Sale)の2つのモデルが存在し、この二つのモデルはUserのidで関連づいています。Userモデル側に記述するリレーションは以下のようになるでしょう。

	public function sales() {
	    return $this->hasMany(Sale::class);
	}

取得のコードは次のようになります。今回はwithで取得します。

User::with('sales')
		->where('id', 2)
		->get();

ユーザーに関連するモデルが取得できました。これは極々一般的なリレーションで取得しています。では次に固定の条件が必要となるケースを説明します。

固定の条件

では次の要件を満たすデータを取得してみましょう。

ユーザーに関連する未発送の商品一覧

この場合、商品の発送状態を管理する必要がありますので、次の仕様とします。Saleモデルのis_shippedがtrueは発送済、falseが未発送を表します。

Userモデルに未発送の商品一覧を取得するリレーションunshippedSalesを新たに作成します。hasManyメソッドで関係するSaleモデルを取得するところまでは前回と同様です。それに加えてwhereをメソッドをチェーンさせてis_shipped = 0の条件をつけてフィルタリングします。

	public function unshippedSales() {
	    return $this->hasMany(Sale::class)
	        ->where('is_shipped', 0);
	}

これで未発送の商品を取得するリレーションは作成できました。取得する処理は以下の通り。

User::with('unshippedSales')
		->where('id', 2)
		->get();

withには作成したunshippedSalesを指定します。これで未発送の商品のみが取得できます。

まとめ

リレーションを作成していると、今回のように固定の条件でフィルタリングできると便利なシーンが出てきます。書き方を覚えておくと役に立つと思いますので是非頭の片隅に置いておいてください。

Laravel

Posted by kobainmac