We use cookies to personalize content and ads, to offer features for social media and to analyze the access to our website. We also share information about your use of our website with our social media, weaving and analytics partners. Our partners may combine this information with other information that you have provided to them or that they have collected as part of your use of the Services. You accept our cookies when you click "Allow cookies" and continue to use this website.

Allow cookies Privacy Policy

Rails guide to implement Like and Unlike

Your app needs a Facebook or LinkedIn kinda Like-Unlike-Feature? See how we implement this pattern with Ruby On Rails.

Coding
Rails Implement Like Unlike Feature


A design pattern for Likes!

Many apps use this feature today. As a user you can like a post, page or even comments. Often a simple "thumbs up" is not enough. As a user of Facebook or LinkedIn you are used to select between different kind of like types.

If you also want to provide multiple types of like-buttons, or other kind of up-down-vote features you are in the right place. This short how-to shows you how to implement a Like feature with RubyOnRails

We do not care about the views in this how-to, because it's up to you what you want to use. You can also take the ideas behind the concept easily adapt it to other frameworks.

The Like model

Let's start with model to track the user likes. Create a new model called like.rb. You can use rails generators or you can add migration and model files manually.

We need 3 things for a like model:

  • Who liked? The user -> user_id
  • Liked what? The reference -> polymorphic association
  • What type of like? Different type of likes -> stored as integer, but could be a string, like you prefer

Database fields for a Like:

create_table :votes do |t|
  t.integer :reference_id
  t.string  :reference_type
  t.integer :user_id
  t.integer :value, default: 0
  t.timestamps null: false
end


Active Record Class for a Like

The Like-class is pretty basic. We have a belongs_to :user and a belongs_to :reference relation. To allow one like per user per reference you can add a uniqueness validator scoped on the reference. For our example we want to provide 5 different kind of like types. So the value has to be between 0 and 4. (Devs should start counting from 0).

class Like < ActiveRecord::Base
  belongs_to :user
  belongs_to :reference, polymorphic: true
  validates_presence_of :value, :user, :reference
  validates :user_id, uniqueness: { scope: [:reference_id, :reference_type] }
  validates :value, inclusion: 0..4
end


Add likes to your post model

To allow your users to like your post you just have to add a has_many :likes relation to your model.

class Post < ActiveRecord::Base
  has_many :likes, as: :reference, dependent: :destroy 
 
  # rest of your class...
end


Add likes to you user model

To get all likes from the user you just have to add this relation to user.rb.

has_many :likes, dependent: :destroy

The Like Controller Class

This is just an example how to implement a controller action for like-unlike feature. If you are using GraphQL you have to put this logic into your mutation resolvers.

Create a class called LikesController under app/controllers/likes_controller.rb. This class will take care of the like-unlike logic. For liking we use create-action. Unlike is actually deleting an entry.

class LikesController < ApplicationController
  # e.g. your auth logic
  # before_filter :authenticate_user!
  
end


Like Action (create)

Set the user id from the current_user and create a new like. 

def create
  # prevent from liking for other users
  params[:like][:user_id] = current_user.id
  @like = Like.new(like_params)
  if @like.save
    flash[:success] = 'Thanks for liking!'
  else
    flash[:alert] = @like.errors.full_messages.join(', ')
  end
end
protected
def like_params
  params.require(:like).permit(:value, :user_id, :reference_id, :reference_type)
end

If you are paranoid you can first check if the given reference still exists in your database.

Unlike Action (destroy)

def destroy
  @like = current_user.likes.find(params[:id])
  @like.destroy
end


Like you can see, these two actions are pretty basic, but they work. You can extend the actions by implementing different kind of respond formats or other special authentication logic (e.g. cancancan).


Change my like (update)

I would not implement an extra action for changing a like. You can hook up a before_create action in your model and delete all previous likes for the reference. In my opinion it is not needed here.


Your views

It's not important in what you are coding your frontend. It might be react.js, or react.native or just the classic RubyOnRails views. The import things are:

  1. Make a like-component or -partial, that you can put this everywhere in your frontend.
  2. For liking: Present up to 5 different kind of like-emojis. For each number between 0 and 4 you show a emoji. If the user clicks on a emoji you have to make a call to the backend with the selected value.
  3. Unlike: Unliking is deleting a like for a user. So in your views you have to know if the user has liked that post.


Conclusion

Rails is a great framework for web development and this small example shows again how easy it is to implement business logic with rails. It's up to you how to go on from here. 


I ❤️Rails,

Simon




Icons made by Freepik from www.flaticon.com

Share this article:

zauberware logo