2011-11-23 65 views
11

試圖做一個範圍在rails3。rails3範圍內has_many關係的子女數

:book has_many :chapters 

我想要範圍:只要返回書籍> 10章。

如何最好地構造這個範圍(不使用計數器緩存)?

謝謝!

+0

爲什麼沒有計數器緩存? –

+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 

幫助?

+0

以下的答案中造成了一些混淆。這是要走的路。我遇到的唯一問題是計數方法在這裏並不像預期的那樣工作。例如,我想,Book.long.count會返回一個包含每本書的章節數的哈希值。你必須做Book.long.all.count。不錯,我猜 –

+3

看起來不錯,但我得到一個錯誤:'列'card_count「不存在'(card_count是我的n_chapters)。 'having'的所有東西似乎都能正常工作,並且在我直接在SQL控制檯中直接運行時,card_count列肯定是填充的... –

+0

我不確定鏈接其他stackoverflow帖子的好做法。但是我對這篇文章有類似的問題,但它只需要has_many對象上的某些屬性。將真正感謝幫助http://stackoverflow.com/questions/31719184/rails-active-record-find-all-records-which-have-a-count-on-has-many-associati –

8

啊 - 回答我的問題在評論上述,我不得不把計數的HAVING:

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

在Rails 4.0這個版本的作品。 你必須在having子句中count()。似乎有句子沒有看到'作爲n_chapters'。

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