当前位置: 首页 > 知识库问答 >
问题:

拉雷维尔-雄辩的“有”、“有”、“哪里有”-它们是什么意思?

桓修能
2023-03-14

我发现这些方法背后的概念和含义有点混乱,有人能在一个例子的上下文中(如果可能的话)向我解释一下之间的区别吗?


共有2个答案

芮岳
2023-03-14

文档已经解释了用法,所以我将使用SQL来解释这些方法。

假设有一个Order(orders)有许多OrderItem(Order\u items)并且您已经建立了它们之间的关系:

// App\Models\Order:
public function orderItems() {
    return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}

这三种方法都是基于一种关系。

结果:with()返回模型对象及其相关结果。

优点:它是一种能防止N 1问题的快速加载。

当您使用以下雄辩的生成器时:

Order::with('orderItems')->get();

Laravel将此代码更改为只有两个SQL:

// get all orders:
SELECT * FROM orders; 
 
// get the order_items based on the orders' id above
SELECT * FROM order_items WHERE order_items.order_id IN (1,2,3,4...);

然后,Laravel通过外键将第二个SQL查询的结果与第一个SQL查询的结果合并,最后返回收集结果。

因此,如果在闭包中选择了不带外键的列,则关系结果将为空:

Order::with(['orderItems' => function($query) { 
           // $query->sum('quantity');
           $query->select('quantity'); // without `order_id`
       }
])->get();

#=> result:
[{  id: 1,
    code: '00001',
    orderItems: [],    // <== is empty
  },{
    id: 2,
    code: '00002',
    orderItems: [],    // <== is empty
  }...
}]

将返回模型的对象时,其关系不是空的。

Order::has('orderItems')->get();

Laravel将此代码更改为SQL查询:

select * from `orders` where exists (
    select * from `order_items` where `orders`.`id` = `order_items`.`order_id`
)

方法whereHas或whereHas在您的has查询中放置where条件。这些方法允许您向关系约束添加自定义约束。

Order::whereHas('orderItems', function($query) {
   $query->where('status', 1);
})->get();

Laravel将此代码更改为SQL查询:

select * from `orders` where exists (
    select * 
    from `order_items` 
    where `orders`.`id` = `order_items`.`order_id` and `status` = 1
)
梁修贤
2023-03-14

with()用于快速加载。这基本上意味着,沿着主模型,Laravel将预加载您指定的关系。如果您有一组模型,并且希望为所有模型加载一个关系,那么这将特别有用。因为使用渴望加载时,您只运行一个额外的DB查询,而不是针对集合中的每个模型运行一个查询。

例子:

用户

$users = User::with('posts')->get();
foreach($users as $user){
    $users->posts; // posts is already loaded and no additional DB query is run
}

have()是根据关系筛选选择模型。所以它的行为非常类似于正常的WHERE条件。如果您只使用have('关系'),这意味着您只想获取在该关系中至少有一个相关模型的模型。

例子:

用户

$users = User::has('posts')->get();
// only users that have at least one post are contained in the collection

whereHas()的工作原理与has()基本相同,但允许您为要检查的相关模型指定其他过滤器。

例子:

用户

$users = User::whereHas('posts', function($q){
    $q->where('created_at', '>=', '2015-01-01 00:00:00');
})->get();
// only users that have posts from 2015 on forward are returned

 类似资料:
  • 我在中编写查询时遇到问题。 我的疑问是 现在我想把这个查询转换成laravel eloquent。

  • 可以在一个集合/json? 使用者- 用户:id | name post:id |用户| id |文本 postimage: id|post_id|imgpath 用户模型: 帖子模式: 从用户处获取所有帖子工作正常: 我能够在一个循环内从帖子中获取所有图像 我想要的是得到所有的帖子,没有循环的图像,例如 谢啦

  • 我是新来的laravel和雄辩,我不确定这是否可能。但是我有2张桌子,有一对多的关系。一个是“位置”,一个是“用户”。一个位置可以有许多用户。 所以,如果我想获得所有用户的所有位置,我会这样做: 但是我也想知道每个位置有多少用户,我试着这样做 但那没有奏效。

  • 我正试图用雄辩加载一个遥远的关系,但遇到了问题。涉及5个表,它们是用户、corporate_users、公司和两个哨兵表(组和users_groups)。 表的设置如下所示: 用户有一个合作用户(一对一) 公司用户归属到公司(多对一) 用户通过users_groups透视表与组建立多对多关系。 所有这些关系都是单独工作的。最初,我可以通过调用

  • 我的客户通过订单订购了许多包裹。 我想退回包裹数量超过0且状态仅为成功的客户。但我不知道如何添加包裹状态的条件。目前,这份声明给了我一份有包裹的客户名单<代码>$customers=Customer::has('包裹','

  • 基本上,我试图在用户、post和回复数据库之间建立一种关系。以下是模型:注释模型 答复方式: 主要代码: 当我进入评论页面时,我得到以下错误: 未定义的属性:照亮\数据库\雄辩\关系\属于::$name。 这是我第一次使用关系,所以我查看了Laravel文档,但仍然不知道我做错了什么。基本上,我试图从用户数据库中获取用户名(使用comments user_id作为外键),获取评论详细信息(body