我有一些项目。这些项目通过会员资格获得用户。
但是,这些用户属于公司。问题是,我如何找出哪些公司可以访问项目?
理想情况下,我可以做project.users.companies,但这不起作用。
这样做有一种愉快,愉快的方式吗?
答案 0 :(得分:1)
我假设你有这个:
class Project < ActiveRecord::Base
has_and_belongs_to_many :users
end
class User < ActiveRecord::Base
has_and_belongs_to_many :projects
belongs_to :company
end
class Company < ActiveRecord::Base
has_many :users
end
你想得到project.companies。我能想象的痛苦之处是:
class Project < ActiveRecord::Base
has_and_belongs_to_many :users
def companies
Company.all(
:joins => {:users => :projects},
:conditions => {'projects_users.project_id' => self.id}
).uniq
end
end
注意最后的uniq。它将删除重复的公司。
答案 1 :(得分:0)
您应该能够将关系设置为允许: project.users.companies 。
协会是:
Project has_one User belongs_to Company
答案 2 :(得分:0)
我认为你可以做这样的事情。
class Project < ActiveRecord::Base
def self.companies
Company.all(:conditions => { :users => { :project_id => @project.id } }, :include => :users)
end
end
但是因为我使用了这些功能已经有一段时间了,所以我可能会生锈。
修改:这可能无效。不确定我是否拥有:include
或:join
权利。但就像我说的那样,我生锈了。
答案 3 :(得分:0)
其他答案似乎忽略了您提到的会员资格。如果这些是你录制的实际对象,那么你选择做什么取决于你的表的大小。如果它们不是非常庞大,那么“更多OO”解决方案可能看起来像这样:
class Project < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :memberships
def user_companies
self.users.map {|user| user.companies}.flatten.uniq
end
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :project
end
class User < ActiveRecord::Base
has_many :memberships
has_many :projects, :through => :memberships
belongs_to :company
end
class Company < ActiveRecord::Base
has_many :users
end
这可能效果不佳,因为它从数据库中提取了大量数据,然后在内存中进行了所有过滤,但阅读起来非常直观。如果你想把所有的计算都推到数据库中,我认为一个好的解决方案可能会在Project类中看起来像这样:
def user_companies
Company.find_by_sql("SELECT company.*
FROM companies, users, memberships
WHERE companies.id = users.company_id
AND users.id = memberships.user_id
AND memberships.project_id = #{self.id}")
end
它有点不太干净,但会使大多数处理最接近数据,并且只有三个表连接不应该最终生成如此大量的元组,使得DBMS在看起来分崩离析。