我使用Laravel 5.3。
我有两张桌子:
Articles
---------
id
cat_id
title
和
Category
---------
id
parent_id
title
我在模特中定义了我的关系:
// Article model
public function category()
{
return $this->belongsTo(Category::class);
}
// Category model
public function children()
{
return $this->hasMany(Category::class, 'parent_id', 'id');
}
使用Eloquent是否有一种简单的方法可以使列表具有文章数量的类别。困难在于我想对id_parent = 0
的类别进行分组,即我只想显示包含儿童文章数量的父类别。
我尝试过类似的东西:
$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');
但我迷失了......
答案 0 :(得分:20)
您可以使用withCount()
。它可以从5.3版本
有关雄辩访问的更多信息:https://laravel.com/docs/5.3/eloquent-relationships
答案 1 :(得分:6)
您可以使用hasManyThrough()
Eloquent方法获取所有儿童文章,然后将文章计数添加到一个漂亮的小吸气剂中。我将getter添加到模型上的$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();
}
}
这是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,
]
>>>
如果要将类别查询限制为包含子文章的文章,可以使用has()
方法执行此操作:
Category::has('children.articles')->get();
以下是has()
方法的更多内容:
https://laravel.com/docs/5.3/eloquent-relationships#querying-relationship-existence
hasManyThrough()
方法:
https://laravel.com/docs/5.3/eloquent-relationships#has-many-through
答案 2 :(得分:2)
在articles()
模型中定义Category
关系:
public function articles()
{
return $this->hasMany(Article::class, 'cat_id');
}
然后你可以尝试:
Category::where('parent_id', 0)->withCount('articles')->get();
答案 3 :(得分:1)
这应该有效:
$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();
上述查询将为您提供类别ID和属于该类别的所有文章的数量。
再次阅读您的问题和评论后,如果我理解正确您想要获得属于这些类别的所有文章的数量(使用parent_id = 0)+属于子类别的文章数量(具有parent_id =的文章数量) (某类别的id))。
现在我无法轻易地对此进行测试,但我认为这些方面的内容应该适用于此。
$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();
那个beign说,我认为你最好在类别中有一个名为count的列,并在每次添加新文章时更新它。为了表现。
答案 4 :(得分:0)
我确信有人还在经历这个,我能够通过以下方式解决它,假设我有一个代理模型和一个Schedule模型,即一个代理可能有很多时间表:
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);
}
}
一些代理可能不一定分配了时间表,因此,我在调用with()
方法之前对其进行了过滤,如下所示:
$agents = Agents::whereIn(
'id',
Schedule::distinct()->pluck('agent_id')
)->with('schedules')->get();
希望这有帮助!