Laravel 路由模型绑定与排序的预加载?

问题描述 投票:0回答:2

我的产品也有评论。该评论可以投票,并且评论也可以有子评论。评论通过预先加载

$with
来加载,这是在
product
模型中定义的,子评论也通过预先加载来加载,这也是在
comments
模型中定义的。子评论也可以投票(但没有任何子评论)。

产品.php(模型)

namespace App;

class Product extends Model
{
    /**
     * @Protected_variables
     */

    protected $with = [
        'comments',
        'user'
    ];

    /**
     * @Relationships
     */

    public function user()
    {
        return $this->belongsTo('App\User');
    }

    public function comments()
    {
        return $this->morphMany('App\Comment', 'commentable');
    }
}

Comment.php(模型)

namespace App;

class Comment extends Model
{
    /**
     * @Protected_variables
     */
     
    protected $with = [
        'children',
        'user'
    ];

    public function user()
    {
        return $this->belongsTo('App\User');
    }

    public function children()
    {
        return $this->hasMany('App\ChildComment');
    }
        
    public function likes()
    {
        return $this->belongsToMany('App\User', 'comments_likes', 'comment_id', 'user_id')->withTimestamps();
    }
}

我使用路由模型绑定在

ProductController.
中接收我的产品 这是路由
Route::get('/product/{product}', ['as' => 'product.show', 'uses' => 'ProductController@show']);
和函数
show
的示例:

产品控制器@show:

public function show(Product $product, Request $request)
{
    if(request()->wantsJson()){
        return response()->json([
            'product' => $product
        ]);
    }

    return view('pages.productDetails')->with([
            'product' => $product
        ]);
}

show
函数中,我现在可以访问产品的
comments
,以及
child comments
comments
以及通过模型中的
$with
属性加载的所有其他关系。

现在有问题了。由于我已经加载了关系,我如何 1. 现在对它们进行排序或 2. 将排序参数传递给模型以获取排序后的关系?

当我写

dd($product->comments->sortByDesc('created_at')->toArray());
时,我会得到我的
product
和按
comments
排序的
created_at
。这就是我想要的。但我无法像这样将排序后的集合分配给
product
集合
$product->comments = $product->comments->sortByDesc('created_at');
因为
$product->comments
@property-read

我也不想再做一次查询并将此

$product->comments()>orderBy('created_at', 'desc')->get();
传递给我的回复。因为模型中的急切加载是多余的。

有没有办法 1. 对关系集合进行排序或 2. 将排序参数传递给模型以获取排序后的关系?

我实际上想坚持我的路由绑定模型。我知道我可以传递排序参数和乘积

id
作为参数,然后通过
get
执行它。但是有没有解决方案可以在模型预加载中做到这一点?

另外,请注意,我还想按喜欢和子评论的数量对我的评论进行排序。我不想仅按日期对它们进行排序,因此在选择数字 2 的解决方案时,我需要将排序参数传递给模型。

亲切的问候!

php laravel sorting eloquent eager-loading
2个回答
0
投票

您可以为关系设置默认顺序或为其创建一个全新的关系。

public function comments()
{
    return $this->morphMany('App\Comment', 'commentable')->orderBy('created_at', 'desc');
}

编辑:如果您决定使用默认订单并需要删除另一个查询,您可以使用

reorder()
参见https://laravel.com/docs/7.x/queries#ordering-grouping-limit-and -偏移


0
投票

使用延迟预加载和附加排序查询。

$product->load([
    'comments' => function ($query) { 
        $query->orderBy('created_at')
    }
]);

https://laravel.com/docs/10.x/eloquent-relationships#lazy-eager-loading

© www.soinside.com 2019 - 2024. All rights reserved.