2012-01-30 41 views
3

我有两个模型公司和角色分别由has_many和belongs_to关联。我需要取得一个拥有“n”个角色的公司。根据关联对象数有效记录查询

我想出了

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

但这不起作用。有没有一个积极的记录解决方案?

谢谢。

回答

8

协会 -

作用belongs_to的:公司

公司的has_many:角色

所以,对于选择的标准是 -

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

OR

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

看起来像我大错特错的关联。你可以把协会放在你的公司和榜样中。 – 2012-01-30 12:42:28

+0

这些协会是一个公司有很多角色和角色属于一个公司。我希望这个就足够了。 – prasvin 2012-01-31 04:16:51

+0

根据上述关联寻找修改后的答案 – 2012-01-31 07:30:40

0

在PostgreSQL中,您可以使用类似select company_fk from roles GROUP BY company_fk HAVING COUNT(company_fk) = 3;之类的东西。

0

不知道这是否适用于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

谢谢。但我想尽可能避免使用复杂查询的形式。 – prasvin 2012-01-31 04:21:54

5

我知道这是不是你要找的答案,但最好的(在性能方面)的解决方案是一个简单的roles_count列添加到companies表,然后添加:counter_cache => true到belongs_to的关联声明。 Rails负责为您更新该列。

然后,

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

的更多信息:http://guides.rubyonrails.org/association_basics.html#belongs_to-counter_cache

+0

+1,完全忘了 – 2012-01-31 08:25:46

+0

+1是的,这是一个很好的解决方案。几乎已经忘记了这一点。谢谢。 – prasvin 2012-01-31 11:55:02

+0

我认为如果我们预计有太多的关联记录,counter-cache会提高性能,否则可能会造成负担过重。说啥 ?? – 2012-01-31 18:50:25