この記事の内容は、Laravel の関連付けモデルの has と with の違いに関するものです (詳細な紹介)。必要な方は参考にしていただければ幸いです。
最初にコードを見てみましょう:
$userCoupons = UserCoupons::with(['coupon' => function($query) use($groupId){ return $query->select('id', 'group_id', 'cover', 'group_number', 'group_cover')->where([ 'group_id' => $groupId, ]); }]) // 更多查询省略...
データ構造は、ユーザー クーポン テーブル (user_coupons)、クーポン テーブル (クーポン)、販売者テーブル (corps)、およびグループの 3 つのテーブルです。クーポン テーブル (group_coupons) (表示しやすいように、最後の 2 つの項目は削除されています)
ここでは、当初、モデルの関連付けを使用して、ユーザー クーポン内の指定されたグループ gourpId に属するすべてのデータを見つける予定でした。 (空の場合、データは返されません)。
しかし、一部の結果は私が望むものではありません:
array(20) { ["id"]=> int(6) ["user_id"]=> int(1) ["corp_id"]=> int(1) ["coupon_id"]=> int(4) ["obtain_time"]=> int(1539739569) ["receive_time"]=> int(1539739569) ["status"]=> int(1) ["expires_time"]=> int(1540603569) ["is_selling"]=> int(0) ["from_id"]=> int(0) ["sell_type"]=> int(0) ["sell_time"]=> int(0) ["sell_user_id"]=> int(0) ["is_compose"]=> int(0) ["group_cover"]=> string(0) "" ["is_delete"]=> int(0) ["score"]=> int(100) ["created_at"]=> NULL ["updated_at"]=> NULL ["coupon"]=> NULL // 注意返回了coupons为空的数据 }
レコード内の一部のクーポンにはレコードがあり、一部は空です。考えてみてください。with は、SQL の in() を使用して実装された、いわゆるプリロードにすぎません。メインの user_coupons データが何であってもリストされます。
これには 2 つの SQL クエリがあり、1 つ目はメイン データをチェックし、2 つ目は関連付けをチェックします。2 つ目の SQL は次のとおりです:
select `id`, `group_id`, `cover`, `group_number`, `group_cover` from `youquan_coupons` where `youquan_coupons`.`id` in (1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14) and (`group_id` = 1) and `youquan_coupons`.`deleted_at` is null
2 つ目の SQL が空の場合、メインレコード 関連するフィールドは NULL です。
後で、Laravel の関連付けられたモデルの has() メソッドを見ました。 has() は既存の関連付けられたクエリに基づいています (同じ効果で、条件を記述するのに便利なだけです)。
ここでのアイデアは、最初のクエリ ロジックにクーポン データがあるかどうかの判断を入れて、空のレコードをフィルターで除外できるようにすることです。
whereHas() を追加した後のコードは次のとおりです。
$userCoupons = UserCoupons::whereHas('coupon', function($query) use($groupId){ return $query->select('id', 'group_id', 'cover', 'group_number', 'group_cover')->where([ 'group_id' => $groupId, ]); })->with(['coupon' => function($query) use($groupId){ return $query->select('id', 'group_id', 'cover', 'group_number', 'group_cover'); }])-> // ...
最後の SQL を見てください:
select * from `youquan_user_coupons` where exists (select `id`, `group_id`, `cover`, `group_number`, `group_cover` from `youquan_coupons` where `youquan_user_coupons`.`coupon_id` = `youquan_coupons`.`id` and (`group_ids` = 1) and `youquan_coupons`.`deleted_at` is null) and (`status` = 1 and `user_id` = 1)
ここでは、実際に存在するレコードをフィルターするためにexists()を使用しています。次に、with() クエリの次のステップに進みます。この時点ですべてがフィルタリングされているため、with は条件を削除できます。
特にリストの場合、2 つの関数を区別することが重要であることは明らかであり、空のデータを特別に除外する必要はなく、ページングを行うのは簡単です。
以上がLaravelアソシエーションモデルにおけるhasとwithの違い(詳細紹介)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。