запрос активной записи в зависимости от количества связанных объектов - PullRequest
3 голосов
/ 30 января 2012

У меня есть две модели Company и Role, связанные ассоциациями has_many и assign_to соответственно.Мне нужно выбрать компанию, которая имеет ровно n ролей.

Я придумал

Company.joins(:roles).having("'count(roles.id) = ?', 3")

, но это не работает.Есть ли активное решение для записи этого?

Спасибо.

Ответы [ 4 ]

8 голосов
/ 30 января 2012

Ассоциации -

роль принадлежит_: компания

компания has_many: роли

Таким образом, выбор для критериев будет -

Company.joins(:roles).group(:company_id).having('count(company_id)= ?', 3)

ИЛИ

Company.joins(:roles).group(:company_id).having('count(*)= ?', 3)
5 голосов
/ 31 января 2012

Я знаю, что это не тот ответ, который вы ищете, но лучшее (с точки зрения производительности) решение - это добавить простой столбец roles_count в таблицу companies, а затем добавить :counter_cache => true в принадлежит к декларации ассоциации. Rails позаботится об обновлении этого столбца для вас.

Тогда

Company.where("roles_count = ?", 3)

Дополнительная информация: http://guides.rubyonrails.org/association_basics.html#belongs_to-counter_cache

0 голосов
/ 30 января 2012

не знаю, будет ли это работать с MySQL, но вы можете попробовать что-то вроде:

Company.joins( <<-SQL_SCRIPT, 3 )
  INNER JOIN ( 
               SELECT    "company_id", COUNT("*")
               FROM      "company_roles"
               GROUP BY  "company_id"
             )
          AS  "filter"
          ON  "filter"."company_id" = "companies"."id"
          AND "filter"."count" = ?
SQL_SCRIPT                   

.где company_roles будет таблицей присоединения для ассоциации HABTM.

0 голосов
/ 30 января 2012

В PostgreSQL вы можете использовать что-то вроде select company_fk from roles GROUP BY company_fk HAVING COUNT(company_fk) = 3;.

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