0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rails】いいね機能について

Posted at

記事概要

Ruby on Railsにいいね機能を実装する方法について、まとめる

前提

  • Ruby on Railsでアプリケーションを作成している

サンプルアプリ(GitHub)

いいね機能

仕組み

ユーザーが好みのツイートに印をつけられる機能
いいねするユーザーといいねされるツイートは多対多の関係

Image from Gyazo
Image from Gyazo

ER図

Image from Gyazo

手順1(必要なモデルを作成)

  1. Likeモデルを作成する
    % rails g model like
    
  2. 必要なカラムを追加するため、マイグレーションファイルを編集する
    db/migrate/20XXXXXXX_create_likes.rb
    class CreateLikes < ActiveRecord::Migration[7.1]
      def change
        create_table :likes do |t|
          t.references :user, foreign_key: true
          t.references :tweet, foreign_key: true
          t.timestamps
        end
      end
    end
    
  3. 下記コマンドを実行する
    % rails db:migrate
    

手順2(アソシエーションを設定)

  1. Likeモデルを編集する
    app/model/like.rb
    class Like < ApplicationRecord
      belongs_to :user
      belongs_to :tweet
    end
    
  2. Tweetモデルを編集する
    app/model/tweet.rb
      # 省略
      
      has_many :likes
    end
    
  3. Userモデルを編集する
    app/model/user.rb
      # 省略
      
      has_many :likes
    end
    

手順3(ルーティングを設定)

  1. likesコントローラーのcreateアクション、destroyアクションを動作させるためのルーティングを設定する
    config/routes.rb
    Rails.application.routes.draw do
      devise_for :users
      root to: 'tweets#index'
      resources :tweets, only: [:index, :new, :create] do
        # createアクションは「いいねする処理」、destroyアクションは「いいねを解除する処理」
        resource :likes, only: [:create, :destroy]
      end
      resources :users, only: [:show]
    end
    

手順4(いいね済かを判定するメソッドを作成)

  1. Tweetモデルにメソッドを定義する
    app/model/tweet.rb
      # 省略
      
      # ユーザーが該当ツイートをいいね済かどうかを判定するメソッド
      def liked_by?(user)
        likes.where(user_id: user.id).exists?
      end
    end
    

手順5(いいねボタンを作成)

  1. いいねボタンを作成するため、app/views/tweets/_tweet.html.erbを編集する
    <div class="tweet">
      <p class = "tweet-text"><%= tweet.text %></p>
      <div class="tweet-name">
        <%= link_to  "投稿者:#{tweet.user.name}", user_path(tweet.user)%>
      </div>
    
      <%#= いいねボタン %>
      <div id="like-btn<%= tweet.id %>">
        <% if user_signed_in? && tweet.liked_by?(current_user)%>
          <%=link_to "いいね済", tweet_likes_path(tweet.id),  data: { turbo_method: :delete }, class: "tweet_likes" %>
        <% else %>
          <%=link_to "いいねする", tweet_likes_path(tweet.id), data: { turbo_method: :post }, class: "tweet_likes" %>
        <% end %>
      </div>
      
    </div>
    
    ※いいねボタンのブロック要素をclassではなくidとしている理由は、いいね機能を非同期化するときに、どのいいねボタンが押されたかを区別する必要があるため
  2. いいねボタンが表示されることを、ブラウザで確認する
    Image from Gyazo

手順6(コントローラーを作成)

  1. likesコントローラーを作成する
    % rails g controller likes
    
  2. create、destroyアクションを定義する
    app/controllers/likes_controller.rb
    class LikesController < ApplicationController
      def create
        like = current_user.likes.build(tweet_id: params[:tweet_id])
        like.save
        redirect_to root_path
      end
    
      def destroy
        like = Like.find_by(tweet_id: params[:tweet_id], user_id: current_user.id)
        like.destroy
        redirect_to root_path
      end
    end
    
  3. いいねボタンを部分テンプレートに切り出す
    1. app/views/likes/_like.html.erbを手動作成する
    2. _like.html.erbを編集する
      <% if user_signed_in? && tweet.liked_by?(current_user)%>
        <%=link_to "いいね済", tweet_likes_path(tweet.id),  data: { turbo_method: :delete }, class: "tweet_likes" %>
      <% else %>
        <%=link_to "いいねする", tweet_likes_path(tweet.id), data: { turbo_method: :post }, class: "tweet_likes" %>
      <% end %>
      
    3. 部分テンプレートを呼び出すため、app/views/tweets/_tweet.html.erbを編集する
        <%#= 省略 %>
        
        <%#= いいねボタン %>
        <div id="like-btn<%= tweet.id %>">
          <%= render partial: "likes/like", locals: { tweet: tweet } %>
        </div>
        
      </div>
      
  4. 「いいね」をクリックした際に、リロードされないことをブラウザで確認する
    Image from Gyazo
  5. 「いいね済」をクリックした際に、リロードされないことをブラウザで確認する
    Image from Gyazo
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?