rails5 progate 整理メモ　いいねボタン

# いいね機能の仕組み
どのユーザーがどの投稿にいいねしたか」をデータとして管理するのがいいね機能。
まずはデータを保存するために、データベースに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のバリデーションを設定
```rb
class Like < ApplicationRecord
  validates :user_id, {presence: true}
  validates :post_id, {presence: true}
end
```

## いいねのデータ作成してみよう
rails consoleを使う。
```rb
[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を返す
```posts.show.html
.
.
.
      <% if Like.find_by(user_id: @current_user.id, post_id: @user.id) %>
        いいね！済み
      <% else %>
        いいね！していません
      <% end %>
.
.
.
```
これでいけるか？
## find_byメソッドの引数で、post_idの値は「@post.id」としてください
```posts.show.html
<% if Like.find_by(user_id: @current_user.id, post_id: @post.id) %>
```
投稿に対して```いいね```をするので```@post.id```を使う
@user.idだとユーザーにいいねをすることになる。

# 「いいね！」ボタンの準備
LikesコントローラーにLikeデータを作成するのでアクションを作らなくてはならない。
## ルーティングを作成する
```routes.rb
 post "likes/:post_id/create" => "likes#create"
```
urlを入力することによってアクションを作動させる。
コントローラーのアクションを作成する。

## Likesコントローラを作成する
```rb
class LikesController < ApplicationController

  before_action :authenticate_user
  
  # createアクションを追加してください
  def create
  end
  
end
```
## 思ったこと
before_actionを答えを見ずによかった。

# 「いいね！」ボタンを作ろう
リンクをいいねのボタンとして作る。
いいねするのは自分。
いいねされるのは投稿。:post_idをparams[:post_id]で使う。
コントローラのcreateアクションを作成する
```likes_controller.rb
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
```
```posts/show.html
      <% 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の要求に何にも当てはまらない。らしい。
```routes.rb
 post "likes/:post_id/create" => "likes#create"
```
ルーティングは合っているはずなんだけと当てはまらない。
```posts/show.html
<%= 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") ^
```likes_controller.rb
.
.
.
redirect_to("/posts/#{params[:post_id}")
.
.
.
```

```rb
redirect_to("<%= "/posts/#{params[:post_id}" %>")
```
にしてみたが上手くいかない。
答えを見た。
```rb
redirect_to("/posts/#{params[:post_id]}")
```
```html
<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
```likes_controller.rb
    @like = LIke.new(user_id: @current_user.id, post_id: params[:post_id])
```
```likes_controller.rb
    @like = Like.new(user_id: @current_user.id, post_id: params[:post_id])
```
```Like```が```LIke```になっていた。