LondonGuy
LondonGuy

Reputation: 11098

How do I implement a likes/+1 kind of feature in my ruby on rails app?

I'm about to add a +1/likes feature to a personal project I'm working on. I'd like to know what the database design for this might look. I don't want to have several like tables but one like table to deal with all likes through out the website. I'd like to be able to "plug in" different parts of the site as they're created or at will.

E.G.

Microposts - users should be able to "like" microposts

Photos - users should be able to "like" photos

Let's say I create a games section and want users to be able to like games I want to be able to use the existing likes table instead of creating a likes table for games.

At the back of my mind I'm thinking the acts_as_tree plugin will be quite useful but could keeping things in the one likes table get messy after a while?

How can I add the likes feature to my app in the most sensible scalable way?

Upvotes: 1

Views: 238

Answers (2)

arieljuod
arieljuod

Reputation: 15838

you should have a "Like" model or something, with, at least, this associations: belongs_to :user belongs_to :liked_object, :polymorphic => true

now you can do

Like.create :liked_object => micropost, :user => current_user

and in a future

Like.create :liked_object => game, :user => current_user

search for polymorphic associations (you may need a liked_object_type and liked_object_id on your migrations)

Upvotes: 1

Damien MATHIEU
Damien MATHIEU

Reputation: 32627

Take a look at polymorphic associations.
The example in the link provided talks about comments, but I think you want the same thing, with likes.

class Like < ActiveRecord::Base
  belongs_to :likable, polymorphic: true
end

class Micropost < ActiveRecord::Base
  has_many :likes, as: :likable
end

class Post < ActiveRecord::Base
  has_many :likes, as: :likable
end

Here, both your Post and Micropost classes can have likes. And you can add some to any classes you want.

You can even do Like.all and, for each like, get the related object (a Post or a Micropost) with like.likable.

Upvotes: 1

Related Questions