我有一个具有多个已定义关系的复杂模型。在此示例中,我希望计算Like
模型并创建名为likes
的属性,以便可以从REST服务返回。
是否可以将模型计数加载到动态属性中?
$beat = Post::with(
array(
'user',
'likes' => function($q){
$q->count();
}
))
->where('id', $id)
->first();
答案 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对象。我假设模型Post
和Like
之间的关系是Post
hasMany
Like
。所以你可以像这样访问计数。
$beat->likes->first()->like_count;
我没有测试上面的代码,但它应该有用。