senfo
senfo

Reputation: 29036

Rails Associations: Access Foreign Value Through Non-Standard Name

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

Answers (2)

micred
micred

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

Ryan Bigg
Ryan Bigg

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

Related Questions