Rails中的深层关系

时间:2010-03-09 00:00:46

标签: ruby-on-rails ruby activerecord

我有一些项目。这些项目通过会员资格获得用户。

但是,这些用户属于公司。问题是,我如何找出哪些公司可以访问项目?

理想情况下,我可以做project.users.companies,但这不起作用。

这样做有一种愉快,愉快的方式吗?

4 个答案:

答案 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在看起来分崩离析。