我的产品也有评论。该评论可以投票,并且评论也可以有子评论。评论通过预先加载
$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 的解决方案时,我需要将排序参数传递给模型。
亲切的问候!
您可以为关系设置默认顺序或为其创建一个全新的关系。
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 -偏移
使用延迟预加载和附加排序查询。
$product->load([
'comments' => function ($query) {
$query->orderBy('created_at')
}
]);
https://laravel.com/docs/10.x/eloquent-relationships#lazy-eager-loading