ruby on rails:find_by_sql的等价语句是什么?

时间:2011-09-03 07:18:55

标签: sql ruby-on-rails ruby ruby-on-rails-3

以下等效的rails语句是什么?

@temp = Post.find_by_sql("SELECT posts.id,posts.title, comment_count.count FROM posts INNER JOIN (SELECT post_id, COUNT(*) AS count FROM comments GROUP BY post_id) AS comment_count ON comment_count.post_id = posts.id  ORDER BY count DESC LIMIT 5;")

是否可以将其转换为find / where / select语句?

这是一个复杂的查询,我无法得到它,但尝试了类似的东西,

@temp = Post.select("posts.id, posts.title, comment_count.count").joins(:comments).group("post_id").order("countpages.counts desc").limit(5)

2 个答案:

答案 0 :(得分:1)

使用像Arel之类的东西可以进一步清理它,我的意思是开始在我的下一个应用程序中使用它(还没有)。

@temp = Post.find_by_sql("SELECT posts.id,posts.title, comment_count.count FROM posts INNER JOIN (SELECT post_id, COUNT(*) AS count FROM comments GROUP BY post_id) AS comment_count ON comment_count.post_id = posts.id ORDER BY count DESC LIMIT 5;")

可能(只是更清洁,但允许你至少链接范围):

@temp = Post.joins("JOIN (SELECT post_id, COUNT(*) AS count FROM comments GROUP BY post_id) AS comment_count ON comment_count.post_id = posts.id").order("count desc").limit(5)

我非常确定Arel会让您通过范围更优雅地进行子选择,但我不熟悉它以便为您提供解决方案。

修改

您可以在counter_cache模型上的comments关联中添加Post,以避免每次都计算它。

class Post < ActiveRecord::Base
  has_many :comments, :counter_cache => true
end

来自here的文档

  

:counter_cache

     

通过缓存关联类的归属对象数   使用increment_counter和decrement_counter。计数器缓存   在创建和减少此类的对象时递增   当它被摧毁。这需要一个名为的列   #{table_name} _count(例如所属的Comment的comments_count   class)用于关联类(例如Post类)。您可以   还可以通过提供列名来指定自定义计数器缓存列   而不是此选项的真/假值(例如:counter_cache =&gt;   :my_custom_counter。)注意:指定计数器缓存会将其添加到   该模型使用attr_readonly的只读属性列表。

答案 1 :(得分:1)

你不需要这里的子查询,你可以简单地说:

Post.select("posts.id, posts.title, COUNT(*) count").
     joins(:comments).
     group('posts.id').
     order('count DESC').
     limit(5)