我如何在两个模型之间做两个has_many / belongs_to关系?

时间:2011-01-18 22:22:58

标签: ruby-on-rails ruby-on-rails-3

我有一个Project模型和一个Contact模型。 Project模型有一个所有者和一个客户端,两者都是Contact个。我显然有些模棱两可的事情,因为如果我有一个联系人并要求它的项目,Rails将无法知道我是否要求它的项目在哪里是客户端或者它是所有者。到目前为止,我有这个:

class Contact < ActiveRecord::Base
  has_many :projects
end

class Project < ActiveRecord::Base
  belongs_to :owner, :class_name => 'Contact', :foreign_key => 'owner_id'
  belongs_to :client, :class_name => 'Contact', :foreign_key => 'client_id'
end

我如何在这里建立两种关系?

3 个答案:

答案 0 :(得分:7)

它类似于在另一个类中定义belongs_to的方式。

基本上是

class Contact < ActiveRecord::Base
  has_many :projects_owned, :class_name => "Project", :foreign_key => "owner_id"
  has_many :projects_as_client, :class_name  => "Project", :foreign_key => "client_id"
end

关联的名称可能会更好。我之前描述的单表继承方法也是一种简洁的方法,但是如果你对每个OwnerContact和ClientContact类有很多不同的行为,那就去做吧,否则它可能只是一个无用的开销。

答案 1 :(得分:2)

我认为这应该是多态关联,就像这样

class Owner < ActiveRecord::Base
  has_many :projects, :as => :person
end

class Client < ActiveRecord::Base
  has_many :projects, :as => :person
end

class Project < ActiveRecord::Base
  belongs_to :person, :polymorphic => true
end

现在,您可以按@client.projects@owner.projects检索项目。如果您想从@project获取人员,您应该将项目迁移添加到:

class CreateProjects < ActiveRecord::Migration
  def self.up
    create_table :projects do |t|
      t.references :person, :polymorphic => true
      t.timestamps
    end
  end
  ...

答案 2 :(得分:1)

您应该尝试在Contact表上使用单个表继承。您需要做的就是实现'type'列(字符串)。 Rails将处理其余的

class Contact < ActiveRecord::Base
   # implement a type column
   has_many :projects
end

class OwnerContact < Contact
end

class ClientContact < Contact
end

class Project < ActiveRecord::Base
  belongs_to :owner, :class_name => 'OwnerContact'
  belongs_to :client, :class_name => 'ClientContact'
end