Laravel Eloquent: 按加载的model.property对结果进行排序,并对结果进行分页
Laravel Eloquent: Order results by eaged loaded model.property, and paginate the result
假设我有三个模型:Post
、Category
和 Tag
。
Post belongsTo
分类和分类 hasMany
Post.
Tag
和 Category
之间存在 manyToMany
关系。
我想按类别名称列出我的帖子并对结果进行分页。
Post::with('category','category.tags')
->orderBy('category.name') //this is the bogus line
->paginate(10);
但是这个语法不起作用。
我试过的是 this 为:
Post::select('categories.*')
->join('categories','posts.category_id','=','categories.id')
->orderBy('categories.name)
->paginate(10);
但是我丢失了急切加载的数据。
如果我删除 select()
子句,那么我会得到垃圾数据,因为 categories.id
会覆盖 posts.id
。参见 here。
有什么优雅的方法可以解决这个问题吗? 在这上面花了几个小时之后,我距离遍历分页帖子和 'manually' 加载关系仅一步之遥:
foreach($posts as $post) {
$post->load('category','category.tags');
}
甚至不确定这是否有缺点,但它似乎不对。如有错误请指正
更新最后一步:急切加载分页结果将不起作用,所以如果我走那条路,我将需要实施更丑陋的修复。
您应该可以同时使用 join
和 with
。
Post::select('posts.*') // select the posts table fields here, not categories
->with('category','category.tags')
->join('categories','posts.category_id','=','categories.id')
->orderBy('categories.name)
->paginate(10);
请记住,with 子句不会改变您的查询。只有查询执行后,才会收集n+1个关系。
您的解决方法确实失去了预先加载的好处。但是你也可以在collection/paginator(查询结果)上调用load(..)
,所以调用->paginate(10)->load('category','category.tags')
等同于上面的查询。
假设我有三个模型:Post
、Category
和 Tag
。
Post belongsTo
分类和分类 hasMany
Post.
Tag
和 Category
之间存在 manyToMany
关系。
我想按类别名称列出我的帖子并对结果进行分页。
Post::with('category','category.tags')
->orderBy('category.name') //this is the bogus line
->paginate(10);
但是这个语法不起作用。
我试过的是 this 为:
Post::select('categories.*')
->join('categories','posts.category_id','=','categories.id')
->orderBy('categories.name)
->paginate(10);
但是我丢失了急切加载的数据。
如果我删除 select()
子句,那么我会得到垃圾数据,因为 categories.id
会覆盖 posts.id
。参见 here。
有什么优雅的方法可以解决这个问题吗? 在这上面花了几个小时之后,我距离遍历分页帖子和 'manually' 加载关系仅一步之遥:
foreach($posts as $post) {
$post->load('category','category.tags');
}
甚至不确定这是否有缺点,但它似乎不对。如有错误请指正
更新最后一步:急切加载分页结果将不起作用,所以如果我走那条路,我将需要实施更丑陋的修复。
您应该可以同时使用 join
和 with
。
Post::select('posts.*') // select the posts table fields here, not categories
->with('category','category.tags')
->join('categories','posts.category_id','=','categories.id')
->orderBy('categories.name)
->paginate(10);
请记住,with 子句不会改变您的查询。只有查询执行后,才会收集n+1个关系。
您的解决方法确实失去了预先加载的好处。但是你也可以在collection/paginator(查询结果)上调用load(..)
,所以调用->paginate(10)->load('category','category.tags')
等同于上面的查询。