Reputation: 6231
I have 2 models: Link
and User
such as:
class Link < ActiveRecord::Base
belongs_to :src_user
belongs_to :dst_user
end
class User < ActiveRecord::Base
has_many :links
end
A schema could looking like:
+----------+ +------+
| Link | | User |
+----------+ |------+
| src_user |---->| |
| dst_user |---->| |
+----------+ +------+
My question is: how can I edit User
model do in order to do this
@user.links # => [list of links]
(...which should query @user.src_users + @users.dst_users, with unicity if possible.)
Can we do this only using SQL inside ActiveRecord? Many thanks.
(note: I'm on Rails 3.1.1)
Upvotes: 1
Views: 1213
Reputation: 106
You have to specify multiple relations inside the user model so it knows which specific association it will attach to.
class Link < ActiveRecord::Base
belongs_to :src_user, class_name: 'User'
belongs_to :dst_user, class_name: 'User'
end
class User < ActiveRecord::Base
has_many :src_links, class_name: 'Link', inverse_of: :src_user
has_many :dst_links, class_name: 'Link', inverse_of: :dst_user
end
The :class_name option must be specified since the association name is not simply :links. You may also need to specify the :inverse_of option in the Link model, but I can't be sure of that. It wouldn't hurt if you did, though.
In order to do your @user.links call, you'll have to do something like this:
class User < ActiveRecord::Base
def links
Link.where(['src_user = ? OR dst_user = ?', self.id, self.id])
end
end
… since ActiveRecord doesn't provide a way to merge two associations on the same model into one.
Upvotes: 3
Reputation: 33954
This sounds very similar to the child/mother/father problem, which has a solution. That is, a problem where an object of one type belongs_to
more than one object of the same type (not necessarily the same type as the child, but the objects it belongs to are themselves the same type).
This solution is quite old, and may not be up to date with the latest style schemes in Rails3, but it should work fine, or with very little modification. http://railsforum.com/viewtopic.php?id=1248
Upvotes: 0