rails3范围,用于has_many关系中的子项数

时间:2011-11-23 23:23:52

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

尝试在rails3中执行范围。

:book has_many :chapters 

我想要范围:很长时间用>返还书籍10章。

如何最好地构建此范围(不使用计数器缓存)?

谢谢!

4 个答案:

答案 0 :(得分:19)

这应该让你前进:

class Book
  scope :long, joins(:chapters).
                 select('books.id, count(chapters.id) as n_chapters').
                 group('books.id').
                 having('n_chapters > 10')
end

有帮助吗?

答案 1 :(得分:8)

啊 - 在上面的评论中回答我自己的问题,我不得不把计数放在HAVING中:

class Book
  scope :long, joins(:chapters).
    select('books.id').
    group('books.id').
    having('count(chapters.id) > 10')
end

答案 2 :(得分:1)

在rails 4.0中,此版本有效。 你必须在having子句中count()。似乎having子句没有看到'as n_chapters'。

答案 3 :(得分:0)

另一种方法是制作子查询。虽然连接更正确(并且可能也会带来更好的性能),但如果组合多个尝试进行分组的范围,最终可能会得到奇怪的结果。子查询的侵入性要小得多。对于此示例,它将类似于:

class Book
  scope :with_chapters_count, -> {
    select('books.*').
    select('(select count(chapters.id) from chapters where chapters.book_id = books.id) as chapters_count')
  }
  scope :long, -> {
    with_chapters_count.where("chapters_count > 10")
  }
end