Laravel雄辩的极限结果 [英] Laravel eloquent limit results

查看:65
本文介绍了Laravel雄辩的极限结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有效的查询:

Object::all()->with(['reviews' => function ($query) {
            $query->where('approved', 1);
        }])

我想限制返回的每个对象的评论数.如果我使用:

And I want to limit the number of reviews, per object, that is returned. If I use:

Object::all()->with(['reviews' => function ($query) {
            $query->where('approved', 1)->take(1);
        }])

Object::all()->with(['reviews' => function ($query) {
            $query->where('approved', 1)->limit(1);
        }])

它限制了评论总数,其中我想限制每个对象返回的评论.我该如何实现?

it limits the total number of reviews, where I want to limit the reviews that are returned by each object. How can I achieve this?

推荐答案

每个父母抓住1个孩子

您可以创建一个助手关系来非常轻松地处理此问题...

Grabbing 1 child per parent

You can create a helper relation to handle this very easily...

在您的Object模型中

public function approvedReview()
{
    return $this->hasOne(Review::class)->where('approved', 1);
}

然后,您只使用它而不是其他关系.

Then you just use that instead of your other relation.

Object::with('approvedReview')->get();


如果需要的数量超过1,事情就会变得复杂得多.我正在调整在 https://softonsofa.com/tweaking-eloquent-relations-how-to-get-n-related-models-per-parent/来解决此问题,并将其用于特质而不是.

If you need more than 1, things start to become quite a bit more complex. I'm adapting the code found at https://softonsofa.com/tweaking-eloquent-relations-how-to-get-n-related-models-per-parent/ for this question and using it in a trait as opposed to a BaseModel.

我创建了一个新文件夹app/Traits,并将新文件添加到该文件夹​​NPerGroup.php

I created a new folder app/Traits and added a new file to this folder NPerGroup.php

namespace App\Traits;

use DB;

trait NPerGroup
{

    public function scopeNPerGroup($query, $group, $n = 10)
    {
        // queried table
        $table = ($this->getTable());

        // initialize MySQL variables inline
        $query->from( DB::raw("(SELECT @rank:=0, @group:=0) as vars, {$table}") );

        // if no columns already selected, let's select *
        if ( ! $query->getQuery()->columns)
        {
            $query->select("{$table}.*");
        }

        // make sure column aliases are unique
        $groupAlias = 'group_'.md5(time());
        $rankAlias  = 'rank_'.md5(time());

        // apply mysql variables
        $query->addSelect(DB::raw(
            "@rank := IF(@group = {$group}, @rank+1, 1) as {$rankAlias}, @group := {$group} as {$groupAlias}"
        ));

        // make sure first order clause is the group order
        $query->getQuery()->orders = (array) $query->getQuery()->orders;
        array_unshift($query->getQuery()->orders, ['column' => $group, 'direction' => 'asc']);

        // prepare subquery
        $subQuery = $query->toSql();

        // prepare new main base Query\Builder
        $newBase = $this->newQuery()
            ->from(DB::raw("({$subQuery}) as {$table}"))
            ->mergeBindings($query->getQuery())
            ->where($rankAlias, '<=', $n)
            ->getQuery();

        // replace underlying builder to get rid of previous clauses
        $query->setQuery($newBase);
    }
}

在您的Object模型中,导入特征use App\Traits\NPerGroup;,不要忘记在类声明下添加use NPerGroup.

In your Object model, import the trait use App\Traits\NPerGroup; and don't forget to add use NPerGroup right under your class declaration.

现在,您想设置一个关系函数以使用特征.

Now you'd want to setup a relationship function to use the trait.

public function latestReviews()
{
    return $this->hasMany(Review::class)->latest()->nPerGroup('object_id', 3);
}

现在您可以像使用其他任何关系一样使用它,它将为每个对象加载最新的3条评论.

Now you can use it just like any other relationship and it will load up the 3 latest reviews for each object.

Object::with('latestReviews')->get();

这篇关于Laravel雄辩的极限结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆