Laravel 模型对象在没有 "get" 方法的情况下使用 where 条件检索关系模型

Laravel model object retrieving relation model with where condition without "get" method

我正在研究 octoberCMS(laravel 框架),我对在 where 子句上检索关系模型有疑问。

我根据主键 "id" 从 "clothing type" 模型中提取了一条 clothing_type 记录。

$clothing_type  = ClothingType::where('id',post('clothingtype_id'))->where('status','Active')->first();

此"clothing type"型号与"products"型号相关联,关系为=>每个服装类型有许多产品。

一切正常;现在我的业务逻辑有两种情况,一种是获取服装类型的所有商品,一种是获取服装类型的第一个商品。所以我使用了 $clothing_type->products 来获取所有产品和 $clothing_type->products->first() 得到第一个产品。

现在我必须为这两种情况应用一个条件。条件是只应获取状态为 "Active" 的产品,因此
$products = $clothing_type->products->where('status','Active'); and
$first_product_detail = $products->first();.

一切都按预期工作,但为什么没有使用 "get()" 方法获取产品。 $clothing_type->products->where('status','Active')->get();因为我是关系的新手,所以我想知道这是如何工作的,或者这是获取记录或不正确假设的坏方法。但一切都很好。

$clothing_type  = ClothingType::where('id',post('clothingtype_id'))->where('status','Active')->first();
if(count($clothing_type->products))
{
    $products               = $clothing_type->products->where('status','Active');
    $first_product_detail   = $products->first();

}

没什么好怕的...

first()where()

Illuminate\Database\Query\Builder 以及 Illuminate\Support\Collection 和所有 first 的函数就是限制记录取1,然后给你第一条记录。当您使用 Builder 进行查询以获取 1 条记录并且 1 条记录用于集合时,所有记录首先是 get() ,然后返回这些记录中的第一条。

这里,

当你这样做时,

$clothing_type->products,Laravel给你一个产品合集...

所以...

$productsIlluminate\Support\Collection

的对象

$products->first() 调用 class 中的 first() 函数。

关于 where and first 集合方法的文档...

你的做法是正确的。当您将关系作为属性访问时,Eloquent 会自动检索记录。

但是,如果您将关系作为一种方法访问,您将获得查询本身,您可以向其添加过滤器:

if(count($clothing_type->products))
{
    $products               = $clothing_type->products()->where('status','Active')->get();
    $first_product_detail   = $products->first();
}

这将解决您的问题

(documentation is over here (see the first item))

编辑:另请注意,第一种方法不是Eloquent的方法,而是来自Collection的方法,非常强大!

编辑2: 我误读了你问题中你想知道这怎么可能的部分。 Eloquent 和 Collections 都有一个 where 方法。我假设您了解 Eloquent 的工作原理,但 Collection 中的那个几乎相同 (see documentation on the Collection where here)

我自己更喜欢 Eloquent,因为它限制了从数据库中检索的记录数量。但是,如果您稍后在代码中需要所有产品(甚至是非活动产品),只需使用 Collection 方法将活动产品过滤掉