Class that belongs_to another Class twice?

I have Class Referral which takes both a giver and receiver as a Person.
As is, @person.referrals returns all referrals as appropriate. Using
built in AR methods, @referral.person returns the receiver of the
referral. To find out who issued the referral, I have created an
instance method “giver” so that @referral.giver returns the Person who
gave it. I looked at Chad F.'s “Self-Referential MtM Models” but
I’m not sure my situation is the same. The current setup I have works,
but I’m not sure if there is a better Rails way to do this.

MIGRATION
class CreateReferrals < ActiveRecord::Migration
def self.up
create_table :referrals do |t|
t.column :giver_id, :integer, :null => false
t.column :receiver_id, :integer, :null => false
t.column :body, :text, :null => false
t.column :created_at, :datetime
end

REFERRAL MODEL
class Referral < ActiveRecord::Base
belongs_to :person

validates_uniqueness_of :giver_id, :scope => :receiver_id

def giver
Person.find(self.giver_id)
end

PERSON MODEL
class Person < ActiveRecord::Base

has_many :referrals, :foreign_key => “receiver_id”

On Dec 19, 2:59 pm, Taylor S. [email protected]
wrote:

def self.up
create_table :referrals do |t|
t.column :giver_id, :integer, :null => false
t.column :receiver_id, :integer, :null => false
t.column :body, :text, :null => false
t.column :created_at, :datetime
end

REFERRAL MODELclass Referral < ActiveRecord::Base
belongs_to :person
has_one :giver, :class_name => “Person”


Posted viahttp://www.ruby-forum.com/.

I think you should be able to just add the has_one association to the
referral model and get your attribute accessor for free…

Best,

-r


Ryan R.
http://raaum.org
http://rails.raaum.org – Rails docs
http://locomotive.raaum.org – Self contained Rails for Mac OS X

REFERRAL MODELclass Referral < ActiveRecord::Base
belongs_to :person
has_one :giver, :class_name => “Person”

Unfortunately this does not work:

VIEW CODE
<% for referral in @referrals %>

#{referral.giver.full_name} <%= referral.body %>

ERROR
Mysql::Error: #42S22Unknown column ‘people.referral_id’ in ‘where
clause’: SELECT * FROM people WHERE (people.referral_id = 4) LIMIT 1

has_one :giver, :class_name => “Person”, :foreign_key => “giver_id”

I knew I should have posted that I tried that too. Well, I tried that
too! The thing is that AR is doing:

belongs_to :person
has_one :giver, :class_name => “Person”
SELECT * FROM people WHERE (people.referral_id = 4) LIMIT 1

belongs_to :person
has_one :giver, :class_name => “Person”, :foreign_key => “giver_id”
SELECT * FROM people WHERE (people.giver_id = 4) LIMIT 1

when it should be doing:

SELECT * FROM people WHERE (people.id = 4) LIMIT 1

try

has_one :giver, :class_name => “Person”, :foreign_key => “giver_id”

On Dec 19, 5:12 pm, Taylor S. [email protected]
wrote:

SELECT * FROM people WHERE (people.id = 4) LIMIT 1


Posted viahttp://www.ruby-forum.com/.

Ok. Here’s what I’ve got…

Migrations

create_table "people" do |t|
  t.column "name", :string
end
create_table "referrals" do |t|
  t.column "giver_id", :integer
  t.column "receiver_id", :integer
end

Models

class Person < ActiveRecord::Base
has_many :referrals, :foreign_key => “receiver_id”
end

class Referral < ActiveRecord::Base
belongs_to :receiver, :class_name => “Person”, :foreign_key =>
“receiver_id”
belongs_to :giver, :class_name => “Person”, :foreign_key =>
“giver_id”
end

Console

r = Person.create
g = Person.create
ref = Referral.create(:giver => g, :receiver => r)

r.reload
g.reload

r.referrals #=> [ ref ]
g.referrals #=> []
ref.giver #=> g
ref.receiver #=> r

Best,

r


Ryan R.
http://raaum.org
http://rails.raaum.org – Rails docs
http://locomotive.raaum.org – Self contained Rails for Mac OS X

Works great, Ryan. Much less hackish than my original solution. Thanks
everyone.