Reputation: 29036
I had to break the Rails convention in order to satisfy a business need and it's causing me some pain. My intention is to be able to reference a foreign table (through Rails) through two separate methods.
In a typical scenario, you'd have something like this:
class Employee < ActiveRecord::Base
belongs_to :company
end
class Company < ActiveRecord::Base
has_many :employees
end
You could then reference a company, through an Employee object doing something like the following:
e = Employee.find(1)
puts e.company.name
That works fine for most tables, but say we have a table like the following:
id - integer default_channel_id - integer and foreign key reference to channel table selected_channel_id - integer and foreign key reference to channel table
As depicted, it's not possible to simply allow the convention to determine how the association is made because more than one column references the same foreign key value.
I've been reading the Rails documentation on associations, but I haven't found anything that allows me to define associations in this way. The closest I got was through the :foreign_key option, but that alone didn't work because it created a single method with the name channel. Following is my attempt:
class Foo < ActiveRecord::Base
belongs_to :channel, :foreign_key => "default_channel_id"
belongs_to :channel, :foreign_key => "selected_channel_id"
end
How should I go about this?
Note: Just in case it helps, I'm working with Ruby 1.9.2 and Rails 3.0.3.
Upvotes: 2
Views: 1046
Reputation: 1532
class Foo < ActiveRecord::Base
belongs_to :default_channel, :class_name => "Channel"
belongs_to :selected_channel, :class_name => "Channel"
end
and
class Channel < ActiveRecord::Base
has_many :default_channels, :foreign_key => 'default_channel_id'
has_many :selected_channels, :foreign_key => 'selected_channel_id'
end
Upvotes: 1
Reputation: 107728
Define the associations like this:
belongs_to :default_channel, :class_name => "Channel"
belongs_to :selected_channel, :class_name => "Channel"
This will reference the default_channel_id
field in your database to load the default_channel
association when you request it and I bet with that information you can work out what happens when you call selected_channel
.
Upvotes: 3