# Terminal
rails g scaffold post user:belongs_to title content
rails g model users_post user:belongs_to post:belongs_to
rails g controller Posts::Likes
rails routes | grep likes
# models/post.rb
class Post < ApplicationRecord
belongs_to :user
has_many :users_posts
has_many :liked_by_users, through: :users_posts, source: :user
# Post.first.liked_by_users.size
end
# models/users_post.rb
class UsersPost < ApplicationRecord
belongs_to :user
belongs_to :post
end
# models/user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :users_posts
has_many :liked_posts, through: :users_posts, source: :post
has_many :posts
end
# controllers/posts/likes_controller.rb
class Posts::LikesController < ApplicationController
def create
post = Post.find(params[:post_id])
current_user.users_posts.create(post: post)
redirect_to post, notice: "Post liked"
end
def destroy
# post = Post.find(params[:post_id])
# current_user.users_posts.find_by(post: post).destroy!
# redirect_to post, notice: "Post unliked"
# users_post = UsersPost.find(params[:id])
# users_post.destroy
# redirect_to post_path(users_post.post_id), notice: "Post unliked"
# users_post = GlobalID::Locator.locate(params[:id])
users_post = GlobalID::Locator.locate_signed(params[:id])
users_post.destroy
redirect_to post_path(users_post.post_id), notice: "Post unliked"
end
end
# config/routes.rb
Rails.application.routes.draw do
resources :posts do
scope module: :posts do
resources :likes, only: [:create, :destroy]
end
end
devise_for :users
root to: 'welcome#index'
end
# controllers/posts_controller.rb
def show
@liked_post = UsersPost.find_by(user: current_user, post: @post)
end
# views/posts/show.html.erb
<%# if current_user.liked_post?(@post.id) %>
<% if @liked_post %>
<%# link_to "unlike", post_like_path(@post, id: @liked_post.to_global_id), method: :delete %>
<%= link_to "unlike", post_like_path(@post, id: @liked_post.to_sgid(expires_in: 1.hour)), method: :delete %>
<% else %>
<%= link_to "like", post_likes_path(@post), method: :post %>
<% end %>