2

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

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

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

2 回答 2

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:相同的逻辑可用于变形许多关系。

于 2014-10-05T20:33:56.417 回答
1

您应该使用 SQLGroup 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 对象。我假设 modelPostLikeis之间的关系Post hasMany Like。所以你可以像这样访问计数。

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

我没有在上面测试过代码,但它应该可以工作。

于 2013-10-05T14:45:11.580 回答