How do you model “Likes” in rails?

前端 未结 4 1597
太阳男子
太阳男子 2021-02-01 09:36

I have 3 models: User, Object, Likes

Currently, I have the model: a user has many Objects. How do I go about modeling:

1) A user can like many objects

2

相关标签:
4条回答
  • 2021-02-01 10:13

    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 => :likes
    end
    
    class Likes < ActiveRecord::Base
      belongs_to :user
      belongs_to :object
    end
    
    class 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.)

    0 讨论(0)
  • 2021-02-01 10:18

    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'
    end
    
    class Like < ActiveRecord::Base
      belongs_to :user
      belongs_to :obj
    end
    
    class 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'   
    end
    
    
    u = User.find(1)
    u.objs # all objects created by u
    u.liked # all objects liked by u
    u.likes # all likes    
    u.likes.collect(&:obj) # all objects liked by u
    
    
    o = Obj.find(1)
    o.user # creator
    o.users # users who liked o
    o.liked_by # users who liked o. same as o.users
    o.likes # all likes for o
    o.likes.collect(&:user)
    
    0 讨论(0)
  • 2021-02-01 10:21

    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 => :thing
    end
    
    class Like < ActiveRecord::Base
      belongs_to :user
      belongs_to :thing
    end
    
    class Thing < ActiveRecord::Base
      # your original association
      belongs_to :user
    
      # the like associations
      has_many :likes
      has_many :liking_users, :through => :likes, :source => :user
    end
    
    0 讨论(0)
  • 2021-02-01 10:35

    Models & associations as per naming conventions of rails modeling

    class User < ActiveRecord::Base
      has_many :likes
      has_many :objects, :through => :likes
    end
    
    class Like < ActiveRecord::Base
      belongs_to :user
      belongs_to :object
    end
    
    class Object < ActiveRecord::Base
      belongs_to :user
    
      has_many :likes
      has_many :users, :through => :likes    
    end
    

    Also, you can use of already built-in gems like acts-as-taggable-on to have same functionality without code :)

    0 讨论(0)
提交回复
热议问题