代码之家  ›  专栏  ›  技术社区  ›  Neil Middleton

铁轨中的深厚关系

  •  4
  • Neil Middleton  · 技术社区  · 16 年前

    我有一些项目。这些项目通过成员身份拥有用户。

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

    理想情况下,我可以做project.users.companies,但这行不通。

    有没有一个好的,愉快的方式来做这件事?

    4 回复  |  直到 16 年前
        1
  •  0
  •   animal    16 年前

    其他的答案似乎忽略了你提到的会员资格。如果这些是您有记录的实际对象,那么您选择做什么取决于表的大小。如果它们不是非常大,那么“更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
    

    这可能不会很好地执行,因为它从数据库中提取大量数据,然后在内存中进行所有过滤,但读取起来非常直观。如果您想把所有的计算都推到数据库中,我认为一个好的解决方案可能会在项目类中看起来像这样:

    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看起来好像要崩溃了。

        2
  •  1
  •   kikito    16 年前

    我假设你有这个:

    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。它将删除重复的公司。

        3
  •  0
  •   Alex Wayne    16 年前

    我想你可以做这样的事。

    class Project < ActiveRecord::Base
      def self.companies
        Company.all(:conditions => { :users => { :project_id => @project.id } }, :include => :users)
      end
    end
    

    但我用这些功能已经有一段时间了,所以我可能生锈了。

    编辑: 这可能不起作用。不确定我有没有 :include 或 :join 正确的。但就像我说的,我生锈了。

        4
  •  0
  •   Toby Hede    16 年前

    您应该能够将关系设置为允许: 项目.用户.公司 .

    这些关联包括:

    Project has_one User belongs_to Company
    
    推荐文章