いいね機能の仕組み
どのユーザーがどの投稿にいいねしたか」をデータとして管理するのがいいね機能。
まずはデータを保存するために、データベースにlikesテーブルを作成する。
likesテーブル
「user_id」と「post_id」2つのカラムを持つlikesテーブルを用意
likeテーブルを作成
Likeモデルとマイグレーションファイルを用意しましょう。
likesテーブルにはuser_idとpost_idの2つのデータを持たせるようにしてください。
rails g model Like user_id:integer post_id:intger
許可されていないコマンドです
rails g model Like user_id:integer post_id:integer
integerのe
が抜けていた。
likeモデルが作成されていた。
マイグレーションファイルを作成するとこれを行う。
rails db:migrate
user_idとpost_idのバリデーションを設定
class Like < ApplicationRecord
validates :user_id, {presence: true}
validates :post_id, {presence: true}
end
いいねのデータ作成してみよう
rails consoleを使う。
[1] pry(main)> like = Like.new(user_id: 1, post_id: 2)
=> #<Like:0x0000559986484160 id: nil, user_id: 1, post_id: 2, created_at: nil, updated_at: nil>
[2] pry(main)> like.save
(0.1ms) begin transaction
SQL (0.3ms) INSERT INTO "likes" ("user_id", "post_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 1], ["post_id", 2], ["created_at", "2022-05-17 05:16:14.991075"], ["updated_at", "2022-05-17 05:16:14.991075"]]
(7.0ms) commit transaction
=> true
likeテーブルに追加することができた。
いいねした投稿かどうか表示しよう
「ログインしているユーザーがその投稿にいいねしたデータが存在する条件をつける
find_by
を使い、条件をつける。
find_by
find_byは該当するデータが見つからなかった時にnilを返す
.
.
.
<% if Like.find_by(user_id: @current_user.id, post_id: @user.id) %>
いいね!済み
<% else %>
いいね!していません
<% end %>
.
.
.
これでいけるか?
find_byメソッドの引数で、post_idの値は「@post.id」としてください
<% if Like.find_by(user_id: @current_user.id, post_id: @post.id) %>
投稿に対していいね
をするので@post.id
を使う
@user.idだとユーザーにいいねをすることになる。
「いいね!」ボタンの準備
LikesコントローラーにLikeデータを作成するのでアクションを作らなくてはならない。
ルーティングを作成する
post "likes/:post_id/create" => "likes#create"
urlを入力することによってアクションを作動させる。
コントローラーのアクションを作成する。
Likesコントローラを作成する
class LikesController < ApplicationController
before_action :authenticate_user
# createアクションを追加してください
def create
end
end
思ったこと
before_actionを答えを見ずによかった。
「いいね!」ボタンを作ろう
リンクをいいねのボタンとして作る。
いいねするのは自分。
いいねされるのは投稿。:post_idをparams[:post_id]で使う。
コントローラのcreateアクションを作成する
class LikesController < ApplicationController
before_action :authenticate_user
def create
# 変数@likeを定義してください
@like = LIke.new(user_id: @current_user.id, post_id: params[:post_id])
# 変数@likeを保存してください
@like.save
# 投稿詳細ページにリダイレクトしてください
redirect_to("/likes/#{params[:post_id}/create")
end
end
<% if Like.find_by(user_id: @current_user.id, post_id: @post.id) %>
いいね!済み
<% else %>
<!-- 以下の1行をcreateアクションへのリンクに書き換えてください -->
<%= link_to("いいね!", "likes/#{@post.id}/create", {method: "post"}) %>
<% end %>
Routing Error
No route matches [POST] "/posts/likes/7/create"
どういうことだろう?
POSTの要求に何にも当てはまらない。らしい。
post "likes/:post_id/create" => "likes#create"
ルーティングは合っているはずなんだけと当てはまらない。
<%= link_to("いいね!", "/likes/#{@post.id}/create", {method: "post"}) %>
/
が書かれていなかった。
成功!
SyntaxError in LikesController#create
app/controllers/likes_controller.rb:12: syntax error,
unexpected tSTRING_DEND, expecting ']' _to("/likes/#{params[:post_id}/create") ^
.
.
.
redirect_to("/posts/#{params[:post_id}")
.
.
.
redirect_to("<%= "/posts/#{params[:post_id}" %>")
にしてみたが上手くいかない。
答えを見た。
redirect_to("/posts/#{params[:post_id]}")
<img src="<%= "/user_images/#{post.user.image_name}"%> ">
この二つの違いはなんだろう?
rubyとHTMLの違い
解決
HTMLの中にERB(Embedded Ruby)も書かれています。
ERBとは、ドキュメントに埋め込まれたRubyコードを評価するテンプレートシステムのことです。
<% %>
と<%= %>
という2種類のERBタグが使われています。
<% %>
タグは「この中のRubyコードを評価する」という意味です。
<%= %>
タグは「この中のRubyコードを評価し、返された値を出力
する」という意味です。
出典 https://railsguides.jp/getting_started.html
Embedded
埋め込み
HTMLの中で埋め込んでいるから<% %>
と<%= %>
を使うのであって、ruby内ならば使わなくていいのか!
NameError in LikesController#create
uninitialized constant LikesController::LIke
@like = LIke.new(user_id: @current_user.id, post_id: params[:post_id])
@like = Like.new(user_id: @current_user.id, post_id: params[:post_id])
Like
がLIke
になっていた。