簡體   English   中英

Laravel eloquent 獲取關系計數

[英]Laravel eloquent get relation count

我使用 Laravel 5.3。

我有 2 張桌子:

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');

但是我迷路了……

您可以使用withCount() 從5.3版本起可以使用

有關雄辯性訪問的更多信息: https : //laravel.com/docs/5.3/eloquent-relationships

您可以使用hasManyThrough()雄辯的方法來獲取所有兒童文章,然后在一個不錯的小吸氣器中將文章計數加在一起。 我將吸氣劑$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();
    }
}

這是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

在您的Category模型中將articles()關系定義為:

public function articles() 
{
    return $this->hasMany(Article::class, 'cat_id');
}

然后,您可以嘗試以下操作:

Category::where('parent_id', 0)->withCount('articles')->get();

這應該工作:

$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();

那個良心說,我認為您最好在類別中創建一個名為count的列,並在每次添加新文章時對其進行更新。 為了表現。

  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');
        }

我確定有人仍在進行此操作,我可以通過以下方式解決此問題,假設我有一個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);
  }
}

好吧,有些代理不一定必須分配調度,因此,我在調用with()方法之前過濾了調度,如下所示:

$agents = Agents::whereIn(
    'id', 
    Schedule::distinct()->pluck('agent_id')
)->with('schedules')->get();

希望這可以幫助!。

關於 Carlos_E. 的回答。 您可以使用 whereHas 而不是 whereIn 來改進查詢:

$agents = Agents::whereHas('schedule')
)->with('schedules')->get();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM