Рельсы считая через отношения - PullRequest
0 голосов
/ 03 марта 2012

У меня проблемы с тем, чтобы обдумать это.

У меня есть четыре модели: Account имеет много-> List имеет много-> ListItem <- относится к <code>Category

Мне нужно получить список топ-n категорий и количество количеств - те, которые имеют наиболее связанные ListItem с. Чтобы сделать его более сложным, у учетной записи есть «роль» (скажем, «руководитель группы» и «менеджер», и количество должно быть разделено этой ролью. Подводя итог, мне нужно следующее:

Top 5 Categories for Team Lead: Category122 (74), Category342 (67), Category22 (52), Category992 (50), Category12 (47) 
Top 5 Categories for Manager: Category1 (174), Category32 (112), Category22 (88), Category92 (73), Category5 (72) 

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

Кто-нибудь знает, как можно рассчитать этот тип вещей?

Ответы [ 2 ]

1 голос
/ 03 марта 2012

Добавьте это к вашей Account модели:

has_many :list_items, :through => :lists

Тогда вы можете сделать это:

a = Account.first
a.list_items.joins(:category).group("categories.name").count
# => {"foo"=>1, "bar"=>2}

РЕДАКТИРОВАТЬ

@categories = Category.select("categories.name AS name, accounts.role AS role, count(list_items.id) AS count")
.joins(:list_items => {:list => :account})
.group("categories.name, accounts.role")
.order("count desc")
.limit(5)

@categories[0].role
# => Team Leader
@categories[0].count
# => 5

Вам нужно будет добавить поля категории в выборку, и запрос будет выглядеть примерно так:

SELECT categories.name, accounts.role, count(list_items.id) 
FROM list_items INNER JOIN lists ON lists.id = list_items.list_id 
INNER JOIN categories ON categories.id = list_items.category_id 
INNER JOIN accounts ON lists.account_id = accounts.id 
GROUP BY categories.name, accounts.role;
0 голосов
/ 03 марта 2012

Вы можете попробовать что-то вроде этого:

top_team_lead_categories = Category.all(
  :joins => {:list_item => {:list => :account}},
  :select => "categories.*, sum(if(list_items.category_id = categories.id, 1, 0)) as list_items_count",
  :conditions => ['accounts.role =?', 'team lead'],
  :group => 'categories.id',
  :order => 'list_items_count desc'
)
...