Rails3 область для подсчета детей в has_many отношениях

пытается сделать область в rails3.

:book has_many :chapters 

Я хочу область: долго возвращать книги s > 10 разделами.

Как лучше структурировать эту область (без использования счетного кеша)?

спасибо!

Ответ 1

Это должно вас заставить:

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

Помогает ли это?

Ответ 2

Ah - чтобы ответить на мой собственный вопрос в комментарии выше, мне пришлось поместить счет в HAVING:

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

Ответ 3

В rails 4.0 эта версия работает. Вы должны считать() в условии наличия. Кажется, что предложение clause не видит "как n_chapters".

Ответ 4

Альтернативой является создание подзапроса. Хотя соединение более корректно (и, возможно, также приводит к повышению производительности), вы можете получить странные результаты, если объединить несколько областей, которые пытаются выполнить группировку. Подзапрос гораздо менее интрузивен. Для этого примера это будет примерно так:

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