2014-09-29 46 views
2

我想要計算ScripRating對於某個Script的upvotes和downvotes的數量。相關模型的Laravel計數列

的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) }} 

回答

3

您可以使用

{{ $script->ratings->count() }}

這將顯示腳本具有的總評分數。

但是,您感興趣的是將收視率分組爲upvotesdownvotes,因此您需要通過group by子句查詢您的關係。

Script::where('title', '=', $title)->with(array(
    '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 loadinglazy 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())

+0

感謝您的評論。我試過上面的代碼,但我無法弄清楚如何使用它。我如何檢索向下/向上投票?另外,你知道我的第二個問題的答案嗎? – JasonK 2014-09-29 17:51:30

+0

謝謝!你可以在我的第一篇文章中看到我做了什麼。我現在遇到的唯一問題是這個錯誤:'類Illuminate \ Database \ Eloquent \ Builder的對象無法轉換爲字符串'這在腳本沒有任何評級時發生。你知道如何解決這個問題嗎? – JasonK 2014-09-29 19:15:51

1

您可以添加到Script MOD EL級的2個功能:

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 }} 
+0

我這樣做,但它給了我SQL語法錯誤。另外,如果我明白這個權利,這將返回向下和upvotes的總數。我需要這些數據,但我也需要單獨提供讚揚和降價。對不起,如果我的英語不夠用。 – JasonK 2014-09-29 17:59:12

+0

@JasonK有一個錯字。現在看,如果你有錯誤,你應該總是提供完整的錯誤信息 – 2014-09-29 18:20:06

+0

是的,我已經注意到't'丟失。語法錯誤:'near'*)與script_rating的總和,其中script_rating.script_id =? (SQL:select script_id,sum(*)as sum from script_rating where script_rating.script_id = 1 group by script_id limit 1)(View:C:\ xampp \ htdocs \ laravel \ laravel \ app \ views \ script.blade。php)' – JasonK 2014-09-29 18:22:54