views:

130

answers:

3

Given two model classes, Foo and Bar, I want Foo to have 3 references to separate instances of Bar using 3 different property names, with the foreign key on the Foo table. Bar will be managed separately and can belong to many instances of Foo. This somewhat explains it, obviously has_one is the wrong association to use (I think?):

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

Bar

There are 3 potential types of Bar, denoted by a bar_type string field, each reference on Foo corresponds to one of these. e.g. Foo.prop_a references an instance of Bar with bar_type = 'type_a'. How do I create this type of association in Rails?

+1  A: 

Why not use inheritance. You can create 3 classes which inherit from Bar. All you need to do is have a type column in your database.

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

Then you migration would need to have bara_id, barb_id and a barc_id column.

I have not tried this but it should work.

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
Will
+1  A: 

Hi Rory!

You are right that the wrong association is being used here.

In ActiveRecord, they model that has the foreign key always belongs_to another model.

In this scenario class Foo actually belongs_to those props

One way to specify this would be:

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

What this means though, is that you must have a column on Foo titled "prop_a_id, prop_b_id, and prop_c_id" which can store the integer that is the primary key of the Bar table.

This solution, however, does not take care of the problem listed below the ActiveRecord associations. For the solution Will proposed above, you would need to take a look at Rails and Single Table Inheritance. If you google this you can find many resources on it. Personally, I recommend Agile Web Development with Rails. In the 3rd edition you can find it on page 377. Also there is a good beginner write-up on STI here

Good luck!

BushyMark
A: 

Would a polymorphic join handle the relationships? http://guides.rubyonrails.org/association%5Fbasics.html#polymorphic-associations

inkdeep