【问题标题】:Laravel route model binding with sorted eager loading?Laravel 路由模型绑定与排序的急切加载?
【发布时间】:2020-12-16 10:39:48
【问题描述】:

我的产品也有 cmets。这个 cmets 可以被投票,并且 cmets 也可以有子 cmets。 cmets 通过在 product 模型中定义的预加载 $with 加载,子 cmets 也通过在 comments 模型中定义的预加载加载。子 cmets 也可以投票(但没有子 cmets)。

Product.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的示例:

ProductController@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,以及commentschild comments 以及通过模型中的$with 属性加载的所有其他关系.

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

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

我也不想再做一次查询并将这个$product->comments()>orderBy('created_at', 'desc')->get(); 传递给我的回复。因为那时模型中的急切加载是多余的。

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

我实际上想坚持我的路由绑定模型。我知道我可以将排序参数和产品id 作为参数传递,然后通过get 执行它。但是在模型预加载中是否有解决方案?

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

亲切的问候!

【问题讨论】:

    标签: php laravel sorting eloquent eager-loading


    【解决方案1】:

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

    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-offset

    【讨论】:

    • 但正如您所说,这现在是默认顺序。如何传递排序参数?我想按comment 日期、comment 喜欢和child comments 的数量/comment 进行排序
    猜你喜欢
    • 2017-03-17
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 2013-05-16
    • 2020-09-08
    • 2013-03-27
    • 2020-05-05
    相关资源
    最近更新 更多