[英]Laravel eloquent get relation count
I use Laravel 5.3.我使用 Laravel 5.3。
I have 2 tables:我有 2 张桌子:
Articles
---------
id
cat_id
title
And和
Category
---------
id
parent_id
title
I have defined my relations in my models:我在我的模型中定义了我的关系:
// Article model
public function category()
{
return $this->belongsTo(Category::class);
}
// Category model
public function children()
{
return $this->hasMany(Category::class, 'parent_id', 'id');
}
Is there an easy way using Eloquent to have a list a categories with count of articles.有没有一种简单的方法使用 Eloquent 列出一个包含文章数量的类别。 The difficulty is that I want to group categories where
id_parent = 0
, ie I want to display only parent categories with count of articles in children.困难在于我想对
id_parent = 0
的类别进行分组,即我只想显示具有子项文章数的父类别。
I tried something like that:我尝试过这样的事情:
$category = new \App\Models\Category();
$categoryTable = $category->getTable();
return $category->leftJoin('article', 'article.cat_id', '=', 'category.id')
->whereIn('article.cat_id', function($query)
{
$query->select('cat_id')
->from('categories')
->where('categories.parent_id', ???)
->orWhere($this->tableName .'.cat_id', $id);
})
->groupBy('cat_id');
But I am lost...但是我迷路了……
you can use withCount()
. 您可以使用
withCount()
。 It is available from 5.3 version 从5.3版本起可以使用
for more info about eloquent visit : https://laravel.com/docs/5.3/eloquent-relationships 有关雄辩性访问的更多信息: https : //laravel.com/docs/5.3/eloquent-relationships
You can use the hasManyThrough()
Eloquent method to fetch all of the childrens' Articles, then add the article counts together in a nice little getter. 您可以使用
hasManyThrough()
雄辩的方法来获取所有儿童文章,然后在一个不错的小吸气器中将文章计数加在一起。 I added the getter to the $appends
array on the model to help illustrate it in the Tinker output. 我将吸气剂
$appends
到模型的$appends
数组中,以帮助在Tinker输出中进行说明。
class Category extends Model
{
protected $appends = [
'articleCount'
];
public function articles()
{
return $this->hasMany(Article::class);
}
public function children()
{
return $this->hasMany(Category::class, 'parent_id');
}
public function childrenArticles()
{
return $this->hasManyThrough(Article::class, Category::class, 'parent_id');
}
public function getArticleCountAttribute()
{
return $this->articles()->count() + $this->childrenArticles()->count();
}
}
Here's the Tinker output: 这是Tinker的输出:
Psy Shell v0.8.0 (PHP 7.0.6 — cli) by Justin Hileman
>>> $cat = App\Category::first();
=> App\Category {#677
id: "1",
name: "Cooking",
parent_id: null,
created_at: "2016-12-15 18:31:57",
updated_at: "2016-12-15 18:31:57",
}
>>> $cat->toArray();
=> [
"id" => 1,
"name" => "Cooking",
"parent_id" => null,
"created_at" => "2016-12-15 18:31:57",
"updated_at" => "2016-12-15 18:31:57",
"articleCount" => 79,
]
>>>
If you want to restrict your Category query to ones that have children that have articles, you could do that using the has()
method: 如果要将类别查询限制为具有子项包含文章的查询,则可以使用
has()
方法:
Category::has('children.articles')->get();
Here's more on the has()
method: 这是有关
has()
方法的更多信息:
https://laravel.com/docs/5.3/eloquent-relationships#querying-relationship-existence https://laravel.com/docs/5.3/eloquent-relationships#querying-relationship-existence
And the hasManyThrough()
method: 还有
hasManyThrough()
方法:
https://laravel.com/docs/5.3/eloquent-relationships#has-many-through https://laravel.com/docs/5.3/eloquent-relationships#has-many-through
Define a articles()
relation in your Category
model as: 在您的
Category
模型中将articles()
关系定义为:
public function articles()
{
return $this->hasMany(Article::class, 'cat_id');
}
Then you can try it as: 然后,您可以尝试以下操作:
Category::where('parent_id', 0)->withCount('articles')->get();
This should work: 这应该工作:
$category
->where('categories.parent_id', 0)
->leftJoin('article', 'article.cat_id', '=', 'categories.id')
->select('categories.id', \DB::raw('COUNT(article.id)'))
->groupBy('categories.id')
->get();
The above query will get you category IDs and count of all articles that belong to the category. 上面的查询将为您提供类别ID和属于该类别的所有文章的计数。
After reading your question and comments again, if I understand correctly you want to get the count of all articles that belong to those categories (with parent_id = 0) + the count of articles that belong to sub categories (those with parent_id = (id of some category)). 再次阅读您的问题和评论后,如果我理解正确,您希望获得属于这些类别(parent_id = 0)的所有文章的计数+属于子类别(parent_id =(id为某些类别))。
Now I have no way of testing this easily, but I think something along these lines should work for that. 现在,我无法轻松地对此进行测试,但是我认为应遵循这些思路。
$category
->where('categories.parent_id', 0)
->leftJoin('article', 'article.cat_id', '=', 'categories.id')
->leftJoin('categories as c2', 'c2.parent_id', '=', 'categories.id')
->leftJoin('article as a2', 'a2.cat_id', '=', 'c2.id')
->select('categories.id', \DB::raw('(COUNT(article.id)) + (COUNT(a2.id)) as count'))
->groupBy('categories.id')
->get();
That beign said, I think you're better of having a column named count in categories and update it each time a new article gets added. 那个良心说,我认为您最好在类别中创建一个名为count的列,并在每次添加新文章时对其进行更新。 For performance.
为了表现。
public function NoOfStudent()
{
return $this->hasMany(UserAssignment::class,'assignment_id','id');
}
$assignment = Assignment::select('id','batch_id','title','description','attachment','last_submission_date',DB::raw('(CASE WHEN type = 9 THEN "Quiz Type" ELSE "Descriptive" END) AS assignment_type'),DB::raw('(CASE WHEN status = 1 THEN "Assigned" ELSE "Not Assigned" END) AS status'))
->with('assignmentBatch:id,batch_number')
->where('assignments.instructor_id',auth('api')->user()->id)
->orderBy('created_at','DESC');
if(!$request->user_id){
$assignment =$assignment->withCount('NoOfStudent');
}
I am sure somebody is still going through this, I was able to solve it the following way, suppose I have an Agent model and a Schedule model, ie one agent may have many schedules: 我确定有人仍在进行此操作,我可以通过以下方式解决此问题,假设我有一个Agent模型和一个Schedule模型,即一个agent可能有许多时间表:
class Schedule extends Model {
public function agent() {
return $this->belongsTo(Agent::class, 'agent_id');
}
}
class Agent extends Model {
public function user(){
return $this->belongsTo(User::class);
}
public function schedules(){
return $this->hasMany(Schedule::class);
}
}
Well some agents may not necessarily have schedules assigned, thus, I filtered those before calling the with()
method, like this: 好吧,有些代理不一定必须分配调度,因此,我在调用
with()
方法之前过滤了调度,如下所示:
$agents = Agents::whereIn(
'id',
Schedule::distinct()->pluck('agent_id')
)->with('schedules')->get();
Hope this helps!. 希望这可以帮助!。
In regards to Carlos_E.'s answer.关于 Carlos_E. 的回答。 You can improve the query by using whereHas instead of using whereIn:
您可以使用 whereHas 而不是 whereIn 来改进查询:
$agents = Agents::whereHas('schedule')
)->with('schedules')->get();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.