4

と の 2 つのモデルがSchoolありReviewます。

モデルは次のSchoolようになります。{ID, name, city, state}

モデルは次のReviewようになります。{ID, content, score, school_id}

レビュー モデルのスコアに基づいて上位 10 校をリストするにはどうすればよいですか?

私はおそらく学校モデルの方法を次のように考えました:

class School < ActiveRecord::Base
 def top_schools
   @top_schools = School.limit(10)
   ...
 end
end

そして、それらを<li>リストでループします:

<div>
 <ul>
   <% @top_schools.each do |school| %>
      <li>school.name</li>
   <%end>
 </ul>
</div>

しかし、私はメソッドを終了するtop_schools方法を本当に知りません。

4

4 に答える 4

5

各学校のレビューの平均を作成する必要があります。

MySQL で実行している場合、SQL クエリは次のようになります。

SELECT schools.* FROM schools 
JOIN reviews ON reviews.school_id=schools.id 
GROUP BY schools.id
ORDER BY AVG(reviews.score) DESC
LIMIT 10

Rails での翻訳:

あなたの学校モデルでは:

scope :by_score, :joins => :reviews, :group => "schools.id", :order => "AVG(reviews.score) DESC"

コントローラーで:

@top_schools = School.by_score.limit(10)

範囲に制限を含めないことを選択すると、より柔軟になり、5 または 15 の表示が可能になります。

MySQLリクエストのみをテストしました。Railsの翻訳についてはよくわかりません。

于 2013-02-08T00:02:02.953 に答える
0

編集:私はその答えのレビューモデルを完全に見逃しました。

School.all(:select => "schools.*, AVG(reviews.score) as avg_score", 
:joins => :reviews, 
:group => 'schools.id', 
:order => 'avg_score desc', 
:limit => 10)

ただし、レビューを追加すると、これは遅くなります。total_scoreの答えが好きです。

于 2013-02-07T23:19:54.277 に答える
0

total_score私なら、schools テーブルに新しいフィールドを追加します。デフォルトでは 0 に設定されています。次に、Review モデルにコールバックを追加して、その学校に新しいレビューが追加/更新されたときに、その学校の合計スコアを計算します。

次に、これを行います: School.order("total_score DESC").limit(10)

于 2013-02-07T23:53:08.140 に答える
0

has_one各学校に 1 つのレビュー (および)しかないと仮定すると、belongs_to最初にレビューを並べ替えてから、対応する学校を見つけます。

Review.order('score DESC').first(10).each do |r|
   School.find_by_id(r.school_id)
end
于 2013-02-07T23:28:50.093 に答える