How do you model "Likes" in rails?
To elaborate further on my comment to Brandon Tilley's answer, I would suggest the following:
class User < ActiveRecord::Base # your original association has_many :things # the like associations has_many :likes has_many :liked_things, :through => :likes, :source => :thingendclass Like < ActiveRecord::Base belongs_to :user belongs_to :thingendclass Thing < ActiveRecord::Base # your original association belongs_to :user # the like associations has_many :likes has_many :liking_users, :through => :likes, :source => :userend
You are close; to use a :through
, relation, you first must set up the relationship you're going through:
class User < ActiveRecord::Base has_many :likes has_many :objects, :through => :likesendclass Likes < ActiveRecord::Base belongs_to :user belongs_to :objectendclass Objects < ActiveRecord::Base has_many :likes has_many :users, :through => :likes end
Note that Objects
should has_many :likes
, so that the foreign key is in the right place. (Also, you should probably use the singular form Like
and Object
for your models.)
Here is a simple method to achieve this. Basically, you can create as many relationships as needed as long as you specify the proper class name using the :class_name option. However, it is not always a good idea, so make sure only one is used during any given request, to avoid additional queries.
class User < ActiveRecord::Base has_many :likes, :include => :obj has_many :objs has_many :liked, :through => :likes, :class_name => 'Obj'endclass Like < ActiveRecord::Base belongs_to :user belongs_to :objendclass Obj < ActiveRecord::Base belongs_to :user has_many :likes, :include => :user has_many :users, :through => :likes # having both belongs to and has many for users may be confusing # so it's better to use a different name has_many :liked_by, :through => :likes, :class_name => 'User' endu = User.find(1)u.objs # all objects created by uu.liked # all objects liked by uu.likes # all likes u.likes.collect(&:obj) # all objects liked by uo = Obj.find(1)o.user # creatoro.users # users who liked oo.liked_by # users who liked o. same as o.userso.likes # all likes for oo.likes.collect(&:user)