【发布时间】:2011-11-23 23:23:52
【问题描述】:
试图在 rails3 中做一个范围。
:book has_many :chapters
我希望 scope :long 归还超过 10 章的书籍。
如何最好地构造这个范围(不使用计数器缓存)?
谢谢!
【问题讨论】:
-
你能描述/你正在使用的数据库的帖子吗?我相信这会在下面的答案中造成一些混乱
标签: ruby-on-rails ruby ruby-on-rails-3
试图在 rails3 中做一个范围。
:book has_many :chapters
我希望 scope :long 归还超过 10 章的书籍。
如何最好地构造这个范围(不使用计数器缓存)?
谢谢!
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-3
这应该可以帮助您:
class Book
scope :long, joins(:chapters).
select('books.id, count(chapters.id) as n_chapters').
group('books.id').
having('n_chapters > 10')
end
有帮助吗?
【讨论】:
having 的所有内容似乎都可以正常工作,当我直接在 SQL 控制台中运行它时,card_count 列肯定会被填充...
啊 - 要在上面的评论中回答我自己的问题,我必须将计数放入 HAVING:
class Book
scope :long, joins(:chapters).
select('books.id').
group('books.id').
having('count(chapters.id) > 10')
end
【讨论】:
在 rails 4.0 中,此版本有效。 您必须在有子句中使用 count() 。似乎有子句没有看到'as n_chapters'。
【讨论】:
另一种方法是创建子查询。虽然连接更正确(并且可能还带来更好的性能),但如果您组合多个尝试进行分组的范围,您最终可能会得到奇怪的结果。子查询的侵入性要小得多。对于这个例子,它会是这样的:
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
【讨论】: