1

現在のユーザーが付けた星の数によって上位 3 つのレビューを選ぶ式があります。

@event.reviews.sort_by { |r| -r.stars.select{ |s| s.user_id == current_user.id }.count }.first(3)

問題は、すべてのレビューと星をメモリに取り込み、これを Ruby で行うことです。ストレート SQL でこれを行う以外に、Ruby の代わりにデータベースが大量の計算を行うように、arel で同じことを達成する方法はありますか?

4

1 に答える 1

1

以下を使用できます。ここでは、からのcounter数を表しますstarscurrent_userreview

# Single query with inner join
@event.reviews.joins(:stars)
       .select("reviews.*, stars.id ,SUM(stars.user_id = #{current_user.id}) AS counter ")
       .group("reviews.id ")
       .order("counter DESC").limit(3)

上記の SQL クエリは、 と の内部結合テーブルを作成しreviewsますstars

これらのテーブルのサイズによっては、フェッチ中のイベントに対して熱心にロードreviewsした方が速い場合があります。例えばstars@event

 # Eager loading with separate queries
 @event =  Event.find(params[:id]).includes(:reviews => :stars)

上記のメソッドは、イベントに関連付けられたすべてのレビューのすべての星を取得する単一のクエリを作成します。

stars同じリクエストの他の場所でとを使用している場合はreviews、 でそれらを熱心にロードすることをお勧めしますincludes

于 2013-09-19T03:49:54.227 に答える