将Ruby表达式转换为Arel

时间:2013-09-18 23:38:39

标签: ruby activerecord arel

我有一个表达式,按当前用户给出的星数来选择前三个评论

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

问题在于它将所有评论和星星都记录到内存中并在Ruby中执行此操作。如果没有在直接SQL中执行此操作,有没有办法在arel中实现相同的功能,以便数据库执行大部分计算而不是Ruby?

1 个答案:

答案 0 :(得分:1)

您可以使用以下内容,counter此处代表来自stars的{​​{1}} current_user的{​​{1}}

review

上面的sql查询将创建一个# 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) reviews的内部联接表。

根据这些表的大小,当您获取stars时,为事件加载reviewsstars可能会更快。例如,

@event

上述方法将进行单个查询以获取与该事件相关的所有评论的所有星标。

如果您在同一请求的其他位置使用 # Eager loading with separate queries @event = Event.find(params[:id]).includes(:reviews => :stars) stars,那么最好使用reviews急切加载它们。