问题描述
我有也有评论的产品。此评论可以投票,评论也可以有子评论。注释通过$with
模型中定义的快速加载product
来加载,子注释也通过comments
模型中定义的快速加载来加载。子注释也可以投票(但没有任何子注释)。
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
,child comments
的{{1}}以及通过模型中的comments
属性。
现在有问题了。既然已经加载了关系,如何1.现在对它们进行排序或2.将sort参数传递给模型以获取排序后的关系?
当我写$with
时,我得到的dd($product->comments->sortByDesc('created_at')->toArray());
和product
由comments
排序。这就是我想要的。但是我无法将经过排序的集合分配给created_at
这样的product
集合,因为$product->comments = $product->comments->sortByDesc('created_at');
是$product->comments
。
我也不想再进行查询并将此@property-read
传递给我的响应。因为那样的话,模型中的急切加载是多余的。
有没有一种方法1.对关系集合进行排序或2.将sort参数传递给模型以获取已排序的关系?
我实际上想坚持我的路线绑定模型。我知道我可以将排序参数和乘积$product->comments()>orderBy('created_at','desc')->get();
作为参数传递,然后通过id
执行它。但是,有没有解决方案可以在模型急于加载的情况下做到这一点?
另外,请注意,我也想按喜欢和他们拥有的子评论数对我的评论进行排序。我不想仅按日期对它们进行排序,因此在为数字2选择解决方案时,需要将sort参数传递给模型。
亲切的问候!
解决方法
您可以为关系设置默认顺序或为其建立新的关系。
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