Home > PHP Framework > Laravel > body text

The difference between has and with in Laravel association model (detailed introduction)

不言
Release: 2018-10-18 14:33:50
forward
10594 people have browsed it

The content of this article is about the difference between has and with in Laravel association model (detailed introduction). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

First look at the code:

$userCoupons = UserCoupons::with(['coupon' => function($query) use($groupId){
    return $query->select('id', 'group_id', 'cover', 'group_number', 'group_cover')->where([
        'group_id' => $groupId,
    ]);
}])
// 更多查询省略...
Copy after login

The data structure is three tables: user coupon table (user_coupons), coupon table (coupons), merchant table (corps), and group coupons Table (group_coupons) (for the convenience of viewing, the last two items have been removed)

Here I originally intended to use model association to find out all the data belonging to the given group gourpId in the user coupons (if it is empty, the data will be not returned).

But some results are not what I want:

  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为空的数据
  }
Copy after login

Some coupons in the records have records, and some are empty. Think about it, with is just the so-called preloading implemented using sql's in(). No matter what the main user_coupons data will be listed.

It will have two sql queries, the first one checks the main data, the second one checks the association. The second sql here is as follows:

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
Copy after login

If the second one is empty, the main record The associated field is NULL.

Later I saw the has() method of Laravel's associated model. has() is based on the existing associated query. Below we use whereHas() (the same effect, just more advanced, convenient for writing conditions)

Our idea here is to put the judgment of whether there is coupon data in the first query logic, so that we can filter out empty records.

The code after adding whereHas() is as follows

    $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');
        }])-> // ...
Copy after login

Look at the final 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)
Copy after login

Here actually uses exists() to filter existing records. Then go to the next step of the with() query. Because everything has been filtered at this time, with can remove the condition.

Obviously it is important to distinguish between the two functions, especially in lists. There is no need to specifically filter out empty data, and it is easy to do paging.

The above is the detailed content of The difference between has and with in Laravel association model (detailed introduction). For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:segmentfault.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template