Выбор популярных моделей на основе количества отношений has_many в Rails - PullRequest
2 голосов
/ 12 ноября 2009

У меня есть две модели:

Novel has_many :pages
Page belongs_to :novel

Я хочу перечислить популярные романы по количеству страниц. По сути, я хочу, чтобы новые модели загружались из результатов этого запроса:

select p.novel_id, count(*) as count
from pages p
GROUP BY p.novel_id
ORDER BY count DESC

Я уверен, что в Rails 2.3 есть какой-то милый способ сделать это с помощью named_scope, но я не могу заставить его работать. Плюс, если это сработает, будет ли это медлительно?

Я подумал о том, чтобы хранить page_count в Novel, но это выглядит как нарушение чего-либо (соглашение, нормализация, моя душа).

Ответы [ 3 ]

5 голосов
/ 12 ноября 2009

Похоже, счетчик кэша - это путь. Если вы создадите столбец с именем page_count в таблице романов (с индексом), Rails будет кэшировать количество страниц в самой модели Novel, что делает этот тип запроса очень простым и производительным.

Значение named_scope на модели Novel становится

class Novel < ActiveRecord::Base
  named_scope :popular, :order => 'page_count desc'
end

class Page < ActiveRecord::Base
  belongs_to :novel, :counter_cache => true
end

Для более подробной информации проверьте Счетчик кэша Railscast

2 голосов
/ 12 ноября 2009

Да, это будет довольно медленно. Это не страшная вещь, чтобы кэшировать page_count в вашем романе. Нормализация все хорошо, пока она не повлияет на производительность.

Кэширование дорогих вычислений является сутью большинства оптимизаций.

1 голос
/ 12 ноября 2009

Сохранение counter_cache в романе считается приемлемым в этом вопросе и должно помочь вашему запросу.

In page.rb do:

 belongs_to :novel, :counter_cache => true

И в вашей таблице novels поместите столбец pages_count. Это будет автоматически увеличиваться при создании страниц и уменьшаться при их удалении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...