简体   繁体   中英

How do I do two has_many/belongs_to relationships between two models?

I've got a Project model, and a Contact model. The Project model has an owner and a client, both of which are Contact s. I've obviously got something ambiguous going on, because if I have a contact and ask for its projects, Rails won't know whether I'm asking for it's projects where it's the client or where it's the owner. So far I've got this:

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

How do I make two relationships here?

Its similar to the way belongs_to is defined in the other class.

So Basically

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

names of associations could be better. The Single Table inheritance approach described before me is also a neat way, but go for it if you have a lot of different behaviour for each of the OwnerContact and ClientContact class, otherwise it might be just a useless overhead.

I think here's should be polymorphic association, something like this

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

Now you can retrieve projects by @client.projects or @owner.projects . If you want to get person from @project you should add to Project migration this:

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

You should try to use a single table inheritance on the Contact table. All you need to do for this to work is to implement a 'type' column (string). Rails will handle the rest

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM