前提
- Rails6
- Devise実装
- fontawesome導入
- jQuery導入
- いいね対象の投稿機能を実装
実装の流れ
- モデル作成・アソシエーション定義
- ルーティング設定
- コントローラー実装
- ビューの修正・追加
完成形
fontawesomeのアイコンを使用して、いいねボタンを実装しています
モデル作成・アソシエーションの定義
まずはモデルを作成していきます。今回、モデル名はLikeとします。
モデルのカラムにはどのユーザーがどの記事に対していいねをしたかを判別するために、
user_idとpost_idが必要になります。
rails g model Like user_id:integer post_id:integer
rails db:migrate
has_many :likes, dependent: :destroy
has_many :like_posts, through: :likes, source: :post
has_many :likes, dependent: :destroy
has_many :like_users, through: :likes, source: :user
class Like < ApplicationRecord
belongs_to :user
belongs_to :portfolio
end
中間テーブル
has_many :中間テーブル名(任意)
through :経由するモデル名
source :関連付けの先のモデル名
ルーティング設定
ルーティングを以下のように設定します。
どの記事に属しているかを認識させたいのでPostsにネストさせます。
また、resources
にすると不必要なパスまで生成されてしまうので、
resource
単数形とonlyで指定することで必要なルーティングだけ生成させます。
resource :posts do
resources :likes, only: [:create, :destroy]
end
コントローラー実装
rails g controller likes create destroy
class LikesController < ApplicationController
before_action :set_post
def create
like = Like.new(user_id: current_user.id, post_id: @post.id)
like.save
end
def destroy
like = Like.find_by(user_id: current_user.id, post_id: @post.id)
like.destroy
end
private
def set_post
@post = Post.find_by(id: params[:post_id])
end
end
ビューの作成
ビューの必要なファイルを確認します。
views
├── likes
│ ├──_like.html.erb
│ ├──create.js.erb
│ └──destroy.js.erb
│
└── posts
└──show.html.erb
流れ:
いいねアイコンをクリック
↓
createアクションが実行され、create.js.erbをrender
↓
パーシャル(_like.html.erb)を表示
いいねを外す時も同じ流れです。
記事詳細ページに「いいねボタンのパーシャル」を任意の位置に設置
<div id="like_<%= @post.id %>">
<%= render 'likes/like', post: @post %>
</div>
- jsを発火させるためにidを必ず指定します。
- パーシャル内(_like.html.erb)で記事のidが必要となるので、
@post
インスタンス変数をローカル変数post
にして渡してあげます。
JavaScriptファイルを作成
$('#like_<%=@post.id %>').html("<%= j(render "likes/like", post: @post) %>");
$('#like_<%=@post.id %>').html("<%= j(render "likes/like", post: @post) %>");
html メソッドは、要素の HTML を取得したり 指定した HTML を挿入したりすることができるメソッドです。
パーシャルを作成
- ユーザーがログインしているかどうか確認
- ユーザーがログインしている場合、対象の記事をいいねしているかどうか確認
<% if user_signed_in? %>
ユーザーがログインしている場合
<% if current_user.likes.find_by(post_id: post.id) %>
ユーザーが既に”いいね”をしている場合
<% else %>
”いいね”をしていない場合
<% end %>
<% else %>
ユーザーがログインしていない場合
▷いいねアイコンをクリックでログインページへ遷移
<% end %>
こうなります
↓
<% if user_signed_in? %>
<% if current_user.likes.find_by(post_id: post.id) %>
<%= link_to post_likes_path(post.id), method: :DELETE, remote: true do %>
<i class="fa fa-heart like_icon"></i>
<% end %>
<% else %>
<%= link_to post_likes_path(post.id), method: :POST, remote: true do %>
<i class="fa fa-heart unlike_icon"></i>
<% end %>
<% end %>
<% else %>
<%= link_to new_user_session_path do %>
<i class="fa fa-heart unlike_icon"></i>
<% end %>
<% end %>
remote: :trueを忘れずに
link_toを非同期処理にする際は、remote: :trueを追加します。
デフォルトはfalseです。
.like_icon {
font-size: 20px;
color: #ff69b4;
}
.unlike_icon {
font-size: 20px;
color: #696969;
}
以上でいいね機能が実装できました!