Hat tip to [has_many :through self-referential example] that sent me down the correct path on this. The challenge I had went a little deeper than the aforementioned post, however. I’m going to reuse the friend example, but with a twist.
class Person < ActiveRecord::Base
# id :integer
end
class Friendship < ActiveRecord::Base
# source_friend_id :integer
# target_friend_id :integer
end
In the above contrived example, Person
is a friend who initiated the friendship (source_friend
), and a friend that was sought for friendship (target_friend
). For the friendship, reflection won’t work on either connection, so we need to specify the class_name:
.
class Friendship < ActiveRecord::Base
belongs_to :source_friend, class_name: "Person"
belongs_to :target_friend, class_name: "Person"
end
Including the friendship
would normally be easy. That’s has_many :friendships
. However, there’s no explicit mapping back to Person
for the Friendship
. ActiveRecord will attempt to use friendships.person_id
to no avail, so foreign_key
must be specified to tell ActiveRecord how to map back the has_many
relationship.
class Person < ActiveRecord::Base
has_many :friendships, foreign_key: :source_friend_id
end
Now, the friends you’ve “made” can be mapped by putting the target_friend
as the source for the has_many :through
.
class Person < ActiveRecord::Base
has_many :friendships, foreign_key: :source_friend_id
has_many :made_friends, through: :friendships, source: :target_friend
end