我想计算某ScripRating
Script
的{0}投票数和投票数。
的script.php:
public function ratings()
{
return $this->hasMany('ScriptRating');
}
ScriptRating.php:
public function script()
{
return $this->belongsTo('Script');
}
script_rating数据库表:
id (primary, increments)
script_id(integer)
rating(integer) <-- Can be either 1 (upvote) or -1 (downvote)
检索脚本并显示评分:
$script = Script::where('title', '=', $title)->get();
{{ $script->ratings }}
这很好用,它返回一个数组:[{"id":1,"script_id":1,"rating":1}]
。但此时我被困住了。我怎么能算出某个剧本的总票数和票数呢?
我还有一个小问题,我发现我感到困惑。这与上面的代码相同:
$script = Script::where('title', '=', $title)->with('ratings')->get();
{{ $script->ratings }}
这两种方法之间有什么区别,我应该使用哪种方法?
提前致谢!
修改
我做了三个范围:
public function scopeTotalRating($query, $scriptId) {
return $query->where('script_id', $scriptId)->get()->sum('rating');
}
public function scopeThumbsUp($query, $scriptId) {
return $query->where('script_id', $scriptId)->having('rating', '=', 1)->get()->sum('rating');
}
public function scopeThumbsDown($query, $scriptId) {
return $query->where('script_id', $scriptId)->having('rating', '=', -1)->get()->sum('rating');
}
并显示如下:
{{ ScriptRating::thumbsUp($script->id) }}
答案 0 :(得分:4)
您可以使用
{{ $script->ratings->count() }}
这将显示脚本的总评分数。
但是,您感兴趣的是将评分分组为upvotes
和downvotes
,因此您需要通过group by
子句查询您的关系。
Script::where('title', '=', $title)->with([
'ratings' => function($query) {
$query->groupBy('rating');
})
])->get();
我认为现在返回的集合应按1
和-1
分组。让我知道结果!
编辑:您还可以查看有关查询关系的文档:
http://laravel.com/docs/4.2/eloquent#querying-relations
编辑回复:
不使用group by的最简单方法是单独查询:
$script = Script::where('title', $title)->first();
if ($script) {
$upvotes = ScriptRating::where('script_id', $script->id)->having('rating', '>', 0)->get()->count();
$downvotes = ScriptRating::where('script_id', $script->id)->having('rating', '<', 0)->get()->count();
}
您提到的脚本之间的区别也称为eager loading
或lazy loading
。在查询中指定->with()
时,这称为预先加载。如果您不这样做,则在指定$script->ratings
有关热切/延迟加载的更多信息:
http://laravel.com/docs/4.2/eloquent#eager-loading
编辑其他回复:
如果您想收集仅具有评分的脚本,您可以使用->whereHas('ratings')
功能。您还可以通过执行if语句来检查具有评级的脚本是否存在:
if ($script->ratings->count() > 0) {
// The script has ratings
} else {
// The script does not have ratings
}
如果您不想继续重复此代码,可以使用以下内容将功能放在Script.php
模型中:
public function hasRatings()
{
return $this->ratings->count() > 0;
}
然后你可以这样做:
if ($script->hasRatings())
答案 1 :(得分:1)
您可以向Script
模型类添加这两个函数:
public function ratingsSumRelation()
{
return $this->hasOne('ScriptRating')->selectRaw('script_id, sum(rating) as sum_all')
->groupBy('script_id');
}
public function getRatingSumAttribute()
{
return $this->ratingsSumRelation ?
$this->ratingsSumRelation->sum_all: 0;
}
现在使用以下方式显示总和:
{{ $script->rating_sum }}