ホームページ >PHPフレームワーク >Laravel >Laravelアソシエーションモデルにおけるhasとwithの違い(詳細紹介)

Laravelアソシエーションモデルにおけるhasとwithの違い(詳細紹介)

不言
不言転載
2018-10-18 14:33:5010638ブラウズ

この記事の内容は、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 サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。