\ プログラミング学習奮闘記録 /

Progate学習メモ Ruby on Rails5【SNSを作る⑨〜いいね機能〜】

目次

いいね機能の仕組み

「どのユーザーがどの投稿にいいねしたか」をデータとして管理するのがいいね機能。

まずはデータを保存するために、データベースにlikesテーブルを作成する

likeテーブルの役割

どのユーザー」が「どの投稿」をいいねしたかを記録するために、データベースに「user_id」と「post_id」2つのカラムを持つlikesテーブルを用意する。

【例】

user_idが1、post_idが2のデータは、「id:1のユーザーがid:2の投稿をいいねした」ということを表す

likeテーブルを作成する

コマンドを実行して、Likeモデルとマイグレーションファイルを用意する。

STEP.1 マイグレーションファイルを作成する

《ターミナル》

$ rails g model Like user_id:integer post_id:integer  テーブル名 カラム名 データ名

  • integerは整数を扱うデータ型

STEP.2 データベースに変更を反映する

《ターミナル》

$ rails db:migrate

STEP.3 バリデーションを追加する

いいねのデータは、user_idとpost_idの両方が常に存在していないと不完全なデータとなってしまうため、最初にバリデーションを追加しておく。

《models/like.rb》

class Like< Application

 validates :user_id,{presence: true}

 validates :post_id,{presence: true}

end

  • user_idとpost_idのそれぞれに、値が存在していることをチェックする「presence: true」のバリデーションを追加

いいねのデータを作成してみる

コンソールでlikesテーブルにデータを追加してみる

《ターミナル》

$ rails console

 like = Like.new(user_id: 1, post_id: 2)

 ↑ユーザーidが1の人が、idが2の投稿にいいねしたデータを作成

 like.save

いいねした投稿かどうか表示する

投稿詳細ページでは、「ログインしているユーザーがその投稿にいいねしたデータが存在する」という条件を満たす場合、「いいね!済み」と表示。
逆に、この条件を満たしていない場合には「いいね!していません」と表示。

《posts/show.html.rb》 条件分岐を作成する

<% if Like.find_by(user_id: @current_user.id, post_id: @post.id)%>

いいね!済み

<% else %>

いいね!していません

<% end %>

  • likeテーブルの中ログイン中のユーザーが かつ いいねした投稿データ を満たすデータがあるかどうかをfind_byを用いて確認
  • →likeテーブルの中で、ログイン中のユーザーが投稿にいいねしたデータが存在するかどうか確認する
  • 【復習】find_byは該当するデータが見つからなかった時にnilを返す

いいね!ボタン

実際にいいねしたり、取り消したりできるようにする。

likesコントローラを作成して、likeデータを作成するためのアクションを用意する。

likeコントローラを用意する

今までコントローラは「rails g controller」コマンドで自動生成してきたけど、コマンドを用いるとビューファイルなども自動生成されてしまう。

今回はそれらのビューファイルが必要ないので、コントローラを手動で作る

tweet_app/→app/→controllers/→likes_controller.rb 新規ファイル作成で作る

createアクションを用意する

作成したlikesコントローラに、新たにLikeデータを作成するためのcreateアクションを用意する。

《likes_controller.rb》

class LikesController < ApplicationController
before_action :authenticate_user

def create

end

end

《ルーティング》

post likes/:post_id/create” => “likes#create”

 

  • createはデータベースにデータを作成するアクションなので、ルーティングには「post」を使う
  • URLの部分は「どの投稿をいいねしたのか」という情報を送信するために、「likes/:post_id/create」とする  →「likes/1/create」や「likes/2/create」に対応する

いいねボタンを完成させる

createアクションの中身を書いて、そのアクションへのリンクを「いいねボタン」として、投稿詳細ページに追加する

《likes_controller.rb》

class LikesController < ApplicationController
before_action :authenticate_user

def create

 @like = Like.new(

  user_id: @current_user.id   ← user_idはログイン中のユーザーidから

  post_id: params[:post_id]   ← post_idはparams[:post_id]から値を取得して

 )                 新たにデータを作成する

 @like.save           ←そのデータを保存する

 redirect_to(“/posts/#{params[:post_id]}“) ←作成後は、投稿詳細ページへリダイレクトする

end

end

《ルーティング》

post “likes/:post_id/create” => “likes#create”

作成したcreateアクションへのリンクを用意する

作成したcreateアクションへのリンクを投稿詳細ページに追加する

《posts/show.rb》

<% if Like.find_by(user_id: @current_user.id, post_id: @post.id)%>

いいね!済み

<% else %>

いいね!していません

  ↓これに書き換え

<%= link_to(“いいね!”,”/likes/#{:post.id}/create”,{method: “post”})%>

<% end %>

  • 今までは「いいね!していません」と表示していた部分を、「いいね!」するためのリンクに書き換える
  • createアクションのルーティングはpostですので、link_toメソッドの引数に{method: “post”}を書き忘れないように注意

いいね!取り消しボタンを作る

「いいね!」を取り消す機能を作るために、まずはlikesコントローラにdestroyアクションを作成する

《likes_controller.rb》

def destroy

@like = Like.find_by(        ←削除すべきLikeデータを取得

  user_id: @current_user.id   ← 削除すべきデータは

  post_id: params[:post_id]    受け取った@current_user.idとparams[:post_id]

 )                 

 @like.destroy           ←destroyメソッドを用いて削除

 redirect_to(“/posts/#{params[:post_id]}”)

end

《ルーティング》

post “likes/:post_id/destroy” => “likes#destroy”

destroyアクションへのリンクを用意する

《posts/show.rb》

<% if Like.find_by(user_id: @current_user.id, post_id: @post.id)%>

いいね!済み

↓書き換える

<%= link_to(“いいね!済み”,”/likes/#{:post.id}/destroy”,{method: “post”})%>

<% else %>

<%= link_to(“いいね!”,”/likes/#{:post.id}/create”,{method: “post”})%>

<% end %>

  • 今までは「いいね!済み」と表示していた部分を、「いいね!」を取り消すためのリンクに書き換える

いいね!ボタンをアイコンにする

「Font Awesome」を使って、いいねボタンをハートのアイコンにする

Font Awesomeの読み込み

「Font Awesome」を利用するには、<head>タグ内で読み込みをする必要がある。

共通部分を書くapplication.html.erbに、読み込み用の<link>タグを追加する

《application.html.erb》

<head>

<link rel=”stylesheet” href=”https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css”> ←Font Awesomeの読み込み

</head>

ハートアイコンの表示

<span>に「fa fa-heart」というクラス名をつけることで、ハートアイコンを表示することができるが

link_toメソッドの中ではうまく表示できない。

HTML要素に対してlink_toメソッドを使うには、<%= link_to(URL) do %>と<% end %>の間にHTML要素を書くことで、その部分をリンクにできる。

《posts/show.rb》

<%= link_to(“URL”) do %>

ここにコードを記載する

<% end %>

| 実際にやってみる

<%= link_to(“/likes/#{@post.id}/create”,{method: “post”})%>

 <span class=”fa-fa heart unliked-btn”></span> リンクになるHTML要素

<% end %>

いいね数を取得する

likesテーブルからデータの件数を取得するには、countメソッドを使う。

countメソッドは配列の要素数を取得するメソッドですが、テーブルのデータ数を取得するためにも利用できる。

《ターミナル》

$ rails console

Like.all.count ← Likesテーブルの全データの数を取得

→ 3

Like.where(post_id: 1).count ←likeテーブルの、post_idが1の数

→ 2

《posts.controller》

def show
@post = Post.find_by(id: params[:id])
@user = @post.user
@likes_count = Like.where(post_id: @post.id).count
end

《posts/show.html》

<%= @likes_count %> ←これでカウント数を表示

  • ここは、すでにfind_byで取得した投稿のidなので、params[:id]ではなく、@post.id!

いいね!した投稿の一覧を表示する

あるユーザーが「いいね!」した投稿一覧を表示するようにする。

今回はユーザーに関するページを作成するので、likesコントローラではなく、usersコントローラにlikesアクションを作成する

likesアクションを用意する

《ルーティング》

get “users/:id/likes” => “users#likes”

URL部分はshowアクションと同様に、どのユーザーに関する情報を表示するかを判断するために「users/:id/likes」とする

《users_controller.rb》

def likes

end

《ビュー:user_likes.html.erb》

《users/show.html.erb》

<ul class=”user-tabs”>

<li class=”active”><%= link_to(“投稿”, “/users/#{@user.id}”) %></li>

<li><%= link_to(“いいね!”, “/users/#{@user.id}/likes”) %></li>

</ul>

likesアクションを完成させる

《users_controller.rb》

def likes

 @user = User.find_by(id: params[:id])  ← params[:id]を用いてユーザー情報を取得

 @likes = Like.where(user_id: @user.id)

end

  • whereメソッドを用いてそのユーザーに関するデータをlikesテーブルから取得し、変数@likesに代入

likeアクションのビュー

ikesアクション内で定義した変数@userと@likesを用いて、ビューも完成させる。

あるユーザーが「いいね!」した投稿を1つ1つ表示するようにする

《user_likes.html.erb》

<%= @likes.each do |like| %>

 <% post = Post.find_by(id: like.post_id)%> 変数likeに紐づく投稿を表示

<% end %>

  • 各投稿を1つずつ表示するためには、@likesに対してeach文を用いて、likeに紐付いているpostを表示させる
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次