laravel 4 eloquent eager load relation count

时间:2013-08-11 21:53:53

标签: php laravel laravel-4 eloquent fluent

我有一个具有多个已定义关系的复杂模型。在此示例中,我希望计算Like模型并创建名为likes的属性,以便可以从REST服务返回。

是否可以将模型计数加载到动态属性中?

$beat = Post::with(
         array(
            'user',
            'likes' => function($q){
                $q->count();
            }
        ))
        ->where('id', $id)
        ->first();

2 个答案:

答案 0 :(得分:4)

假设你有Post->hasMany->Like关系并且你宣布喜欢的关系为:

class Post{

  public function likes(){
   return $this->hasMany('Like');
  }
}

创建一个新功能,说likeCountRelation为:

public function likeCountRelation()
{
    $a = $this->likes();

    return $a->selectRaw($a->getForeignKey() . ', count(*) as count')->groupBy($a->getForeignKey());
}

现在您可以将__get()功能覆盖为:

public function __get($attribute)
{

    if (array_key_exists($attribute, $this->attributes)) {
        return $this->attributes[$attribute];
    }

    switch ($attribute) {

        case 'likesCount':
            return $this->attributes[$attribute] = $this->likesCountRelation->first() ? $this->likesCountRelation->first()->count : 0;
            break;

        default:
            return parent::__get($attribute);

    }
}

或者你可以使用getattribute函数:

public function getLikesCountAttribute(){
 return $this->likesCountRelation->first() ? $this->likesCountRelation->first()->count : 0;
}

只需将likesCount作为$post->likesCount访问,您甚至可以像以下一样急切地加载它:

$posts=Post::with('likesCountRelation')->get();
 foreach($post as $post){
  $post->likesCount;
 }

NOTE:可以使用相同的逻辑来变换许多关系。

答案 1 :(得分:1)

您应该使用SQL Group By语句才能使其正常工作。您可以像下面那样重写您的查询。

$beat = Post::with(
         array(
            'user',
            'likes' => function($q) {
                // The post_id foreign key is needed, 
                // so Eloquent could rearrange the relationship between them
                $q->select( array(DB::raw("count(*) as like_count"), "post_id") )
                  ->groupBy("post_id")
            }
        ))
        ->where('id', $id)
        ->first();

likes的结果是具有一个元素的Collection对象。我假设模型PostLike之间的关系是Post hasMany Like。所以你可以像这样访问计数。

$beat->likes->first()->like_count;

我没有测试上面的代码,但它应该有用。