2011-01-18 3 views
2

У меня есть модель Project и модель Contact. Модель проекта имеет владельца и клиента, оба из которых - Contact с. У меня, очевидно, что-то неоднозначное происходит, потому что, если у меня будет контакт и спросить о его проектах, Rails не будет знать, спрашиваю ли я его проекты, где это клиент или где он является владельцем. Пока у меня это есть:Как сделать два отношения has_many/belongs_to между двумя моделями?

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 

Как мне здесь сделать два отношения?

ответ

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, иначе это может быть просто бесполезными накладными расходами.

+0

Это именно то, что мне нужно, спасибо Ришаву! – Skilldrick

1

Вы должны попытаться использовать одно наследование таблицы в таблице контактов. Все, что вам нужно сделать для этого, - это реализовать столбец «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 
+0

Проблема в том, что некоторые контакты могут быть владельцем * и * клиентом. Я думаю, что это может указывать на проблему с моделированием, хотя ... – Skilldrick

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, вы должны добавить в Project mig это:

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

Проблема с этим, как и с предложением Тушарра, заключается в том, что Владелец и Клиент могут быть одним и тем же человеком - я не хочу двух отдельных записей. – Skilldrick

+0

В чем проблема, просто добавьте свойство boolean в Person и создайте методы вроде владельца? и клиент? ? – megas

Смежные вопросы