Rails多对多:通过类属性合并?

时间:2011-03-30 19:15:47

标签: ruby-on-rails ruby activerecord associations

我有以下多对多关系:

class Assignment < ActiveRecord::Base
  belongs_to :programmer
  belongs_to :project
end

class Programmer < ActiveRecord::Base
  has_many :assignments
  has_many :projects, :through => :assignments
end

class Project < ActiveRecord::Base
  has_many :assignments
  has_many :programmers, :through => :assignments
end

在我的db:migrate中,我有以下内容:

class CreateAssignments < ActiveRecord::Migration
  def self.up
    create_table :assignments do |t|
      t.integer :programmer_id
      t.integer :project_id
      t.boolean :owner, :default => false
      t.timestamps
   end
  end

 def self.down
    drop_table :assignments
 end
end

这意味着我可以加载属于程序员的项目:

@my_programmer.projects.find params[:id]

但是,如果您看到我的迁移,则每个分配还有一个“所有者”标志,指示程序员是否是该项目的所有者。我的问题是这个查询只会给我项目,而不能访问“所有者”标志。

那么我怎么知道程序员是否是所有者?我可以再做一次调用以获得合作,但它似乎很愚蠢,因为它已经在分配上加入了吗?

有没有办法在:through类上获取属性,而无需进行特定的数据库调用?

1 个答案:

答案 0 :(得分:0)

这是一个非常奇怪的数据库架构。但你可以试试这个

class Programmer < ActiveRecord::Base
  has_many :assignments
  has_many :projects, :through => :assignments

  def own_projects
    projects.where(:owner => true)
  end
end

class Project < ActiveRecord::Base
  has_many :assignments
  has_many :programmers, :through => :assignments

  def owners
    programmers.where(:owner => true)
  end

  def collaborators
    programmers.where(:owner => false)
  end
end

@my_programmer.own_projects
@my_project.owners
@my_project.owners.include? @my_programmer
@my_project.colaborators

<强> UPD

使用预先加载的另一种解决方案:

class Programmer < ActiveRecord::Base
  has_many :assignments
  has_many :projects, :through => :assignments
  has_many :own_projects, :class_name => "Project", :through => :assignments, :conditions => ['assignments.owner = ?', true], :source => :project
end

class Project < ActiveRecord::Base
  has_many :assignments
  has_many :programmers, :through => :assignments
  has_many :owners, :class_name => "Programmer", :through => :assignments, :conditions => ['assignments.owner = ?', true], :source => :programmer
  has_many :collaborators, :class_name => "Programmer", :through => :assignments, :conditions => ['assignments.owner = ?', false], :source => :programmer
end

@my_programmer.projects.includes(:owners).each do |project|
  project.owner
end