railsのキホンvol.10（いいね!ボタン）

##いいね！ボタン機能
今回実装するいいね！ボタンは投稿詳細ページのハートアイコンをクリックすることで投稿をいいねでき、もう一度クリックすることでいいねを取り消すことができるものとなる。

必要となる情報は
```「どのユーザーがどの投稿をいいねしたか」```
なので、そのデータを保存するlikesテーブルを作成する。

```
$ rails g model Like user_id:integer post_id:integer
.
$ rails db:migrate
 ```

また、常に値がないと不完全なものとなるからバリデーションをしておく。

```models/like.rb
validates :user_id,{presence:true}
validates :post_id,{presence:true}
```

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

```postss/show.html.erb
<% if Like.find_by(user_id: @current_user.id,post_id: @post.id) %>
  いいね！済み
<% else %>
  いいね！していません
<% end %>
```

###いいね!ボタンの準備

実際にいいねしたり取り消したりするために、likesコントローラ作成してLikeデータを保存するためのアクションんを作る。

likesコントローラの場合はビューファイルが必要ないため、手動でコントローラを作っていく。
その中にデータ保存のためのcreateアクションを定義する。

```app/controllers/likes_controller.rb
class LikesController < ApplicationController
 def create
    @like = Like.new(user_id: @current_user.id, post_id: params[:post_id])
    @like.save
    redirect_to("/posts/#{params[:post_id]}")
 end
```
```routes.rb
#likes/1/create
post "likes/:post_id/create" => "likes#create"
```
createアクションでデータ作成後、投稿詳細ページへリダイレクトする。
また、post_idはparamsから取得するようにする。

###createアクションにデータを送る

```postss/show.html.erb
<% if Like.find_by(user_id: @current_user.id,post_id: @post.id) %>
  いいね！済み
<% else %>
  #createアクションへデータを送る
  <%= link_to("いいね！していません","likes/#{@post.id}/create",{method:"post"}) %>
<% end %>
```

##いいね！取り消しボタン
likesテーブルのデータを消す、destroyアクションを定義する
###destroyメソッド

```app/controllers/likes_controller.rb
class LikesController < ApplicationController
 def destroy
    @like = Like.find_by(user_id: @current_user.id, post_id: params[:post_id])
    @like.destroy
    redirect_to("/posts/#{params[:post_id]}")
 end
```
```routes.rb
#likes/1/destroy
post "likes/:post_id/destroy" => "likes#destroy"
```
###destroyアクションにデータを送る

```postss/show.html.erb
<% if Like.find_by(user_id: @current_user.id,post_id: @post.id) %>
  <%= link_to("いいね！済み","likes/#{@post.id}/destroy",{method:"post"}) %>
<% else %>
  #createアクションへデータを送る
  <%= link_to("いいね！していません","likes/#{@post.id}/create",{method:"post"}) %>
<% end %>
```
##いいね！ボタンアイコン

###Font Awesome
Font Awesomeとは、様々なアイコンをフォントとしてフォントとして利用できるようにしたもの。
これを使うには ```<head>タグ``` ないで読み込む必要がある。railsの場合、<head>タグは共通のレイアウトになるから、以下のようにする。

```layouts/application.html.erb
<html>
  <head>
    ...
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
  </head>
```
ハートアイコンの場合、
```<span class="fa fa-heart"></span>```
とすれば表示されるが、link_toメソッドを使う場合は、メソッド内にHTML要素を記述することができないので、以下の方法での記述となる。

```
<%= link_to("url") do %>
 <HTML要素>
<% end %>
```
よって、今回のいいね！ボタンに関してはこのようなソースになる。

```posts/show.html.erb
<% if Like.find_by(user_id: @current_user.id, post_id: @post.id) %>
        <%= link_to("/likes/#{@post.id}/destroy", {method: "post"}) do %>
          <span class="fa fa-heart like-btn-unlike"></span>
        <% end %>
<% else %>
        <%= link_to("/likes/#{@post.id}/create", {method: "post"}) do %>
          <span class="fa fa-heart like-btn"></span>
        <% end %>
 <% end %>
```

##いいね数の取得
いいねの数＝データの件数を取得するには```countメソッド```を使えばいいので
@likes_countをposts/showアクションの中で定義する。

```posts/show.html.erb
@likes_count = Like,where(post_id: @post.id).count
```
これを、ハートアイコンの下に表示させればok。
##いいね！した投稿の一覧表示
いいね！した投稿を一覧で表示するためにuserコントローラの中にlikesアクションを定義する。

```user_controller.rb
def likes

end
```
```routes.rb
get "users/:id/likes" => "users#likes"
```
また、likesアクションの中身は以下の通り。

```user_controller.rb
def likes
@user = User.find_by(id: params[:id])
@plikes = Like.where(user_id: @user.id)
end
```

取得した投稿をeach文により表示させる。

```users/likes.html.erb
<% @likes.each do |like| %>
 <%= post = Post.find_by(id: like.post_id) %>
 ...
<% end %>
```
続き
https://qiita.com/jonnyjonnyj1397/items/c45d3082b2ccb0d31446