Несколько ассоциаций «один ко многим» в одной модели - PullRequest
0 голосов
/ 31 августа 2009

Учитывая два класса моделей, Foo и Bar, я хочу, чтобы Foo имела 3 ссылки на отдельные экземпляры Bar, используя 3 разных имени свойства, с внешним ключом в таблице Foo. Бар будет управляться отдельно и может принадлежать многим экземплярам Foo. Это несколько объясняет это, очевидно, has_one - неправильная ассоциация для использования (я думаю?):

Foo
   has_one :prop_a, :class_name => "Bar"
   has_one :prop_b, :class_name => "Bar"
   has_one :prop_c, :class_name => "Bar"

Bar

Существует 3 возможных типа Bar, обозначаемых строковым полем bar_type, каждая ссылка на Foo соответствует одному из них. например Foo.prop_a ссылается на экземпляр Bar с bar_type = 'type_a'. Как мне создать этот тип ассоциации в Rails?

Ответы [ 3 ]

1 голос
/ 01 сентября 2009

Вы правы, что здесь используется неправильная ассоциация.

В ActiveRecord они моделируют, что имеет внешний ключ, всегда belongs_to другая модель.

В этом сценарии класс Foo на самом деле belongs_to эти реквизиты

Один из способов указать это будет:

class Foo < ActiveRecord::Base
 belongs_to :prop_a, :class_name => "Bar", :foreign_key => "prop_a_id"
 belongs_to :prop_b, :class_name => "Bar", :foreign_key => "prob_b_id"
 belongs_to :prop_c, :class_name => "Bar", :foreign_key => "prob_c_id"
end

Однако это означает, что в Foo должен быть столбец с заголовком "prop_a_id, prop_b_id и prop_c_id", в котором можно хранить целое число, являющееся первичным ключом таблицы Bar.

Это решение, однако, не решает проблему, указанную под ассоциациями ActiveRecord. Для решения, предложенного выше, вам нужно будет взглянуть на Rails и Single Table Inheritance. Если вы гуглите это, вы можете найти много ресурсов на нем. Лично я рекомендую Agile Web Development с Rails. В 3-м издании вы можете найти его на странице 377. Также здесь есть хорошая статья для начинающих по STI здесь

Удачи!

1 голос
/ 31 августа 2009

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

class Foo
  has_one :bara
  has_one :barb
  has_one :barc
end

class BarA < Foo
  belongs_to :foo
end

class BarB < Foo
  belongs_to :foo
end

class BarC < Foo
  belongs_to :foo
end

Тогда для миграции потребуется столбцы bara_id, barb_id и barc_id.

Я не пробовал это, но оно должно работать.

one = Foo.new
two = BarA.new
three = BarB.new
four = BarC.new
one.bara = two
one.barb = three
one.barc = four
one.save

one.bara.foo #=> one
one.bara.bara = BarA.new
one.bara.bara.foo #=> two
0 голосов
/ 02 сентября 2009

Будет ли полиморфное соединение обрабатывать отношения? http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...