ライクの実装

このレッスンでは、routesやコントローラの設定を行ってライクボタンを実装します。ライクとは、そう「いいね」機能ですね。この記事いいなと思ったら押すやつです。今やスタンダードな機能と言っても良いこの機能、これから実装していきます。

routesの設定

routes.rbを以下のように編集して下さい。オピニオンは複数のライクを持つ、というような関連付けがされている場合、以下のように入れ子の形で記述する事が出来ます。

# routes.rb

resources :opinions do
  resources :likes
end

オピニオンコントローラの設定

opinions#showにライクの為の記述を追加します。

def show
  @clip = @opinion.clip
  @opinions = @clip.opinions
  @like = current_user.likes.find_or_initialize_by(opinion: @opinion)
end

ここで注目するコードとしてはこのコードですね。

@like = current_user.likes.find_or_initialize_by(opinion: @opinion)

ライクはユーザーのつけたオピニオンに対して行いますよね。ようするにその意見(オピニオン)が良いと思えば、ライクを押すわけです。ここで問題なのは一度ライクを押したのであれば、そのボタンが押せないように、もしくはライクの解除になってなければいけないですよね。

なのでこの find_or_initialize_by というメソッドを使用します。このメソッドで自分がライクしているかどうかを見極めて、もしなければ新しくライクを作成する準備をします。

正確な意味としては
「current_userのライクしたオピニオンの中に今のオピニオンが入っているか?入っていればそのライクオブジェクトを、なければ新規オブジェクトを作成する」
ということになります。

ライクボタンを実装する

先程作成したライクオブジェクトが新規オブジェクトかどうかで表示方法を変更します。新しいオブジェクトであれば「いいね」ボタンを、ライクオブジェクトに中身が入っていれば「いいねを取り消す」を表示します。

以下のように記述して下さい。

<%= simple_format @opinion.body %>
<% if @like.new_record? %>
  <%= button_to "#{@opinion.likes.count} いいね", [@opinion, @like], class: 'btn btn-danger'%>
<% else %>
  <%= button_to "#{@opinion.likes.count}  いいねを取り消す", [@opinion, @like], class: 'btn btn-default', method: :delete %>
<% end %>

最初のifの部分では、new_record?というメソッドが使われています。これは、レコードが新たに作成されたものかどうかを調べる事が出来るメソッドです。もし既存レコードであった場合は、falseが返るという形になります。

このメソッドを使って、もし@likeが新規作成されたものであればと書かれています。また、その場合はライク数及びライクボタンが表示されるようになっています。

<%= button_to "#{@opinion.likes.count} いいね", [@opinion, @like], class: 'btn btn-danger'%>

@likeに既存ライクレコードが代入されている場合には、ライク取り消しの為のボタンが表示されます。この"button_to"というメソッドは標準でPOSTメソッドになります。なのでここはlikes_controllerのcreateアクションへのリンクとなります。

<%= button_to "#{@opinion.likes.count}  いいねを取り消す", [@opinion, @like], class: 'btn btn-default', method: :delete %>

ここはmethod: :deleteとなっていますのでDELETEメソッドになります。なのでlikes_controllerのdestroyアクションへのリンクとなります。

ライクコントローラの設定

likes_controller.rb#createを以下のように編集します。@likeでは親となるオピニオンに紐づくように設定しています。また、だれがライクを押したのかという情報も加えるようになっています。

def create
  @opinion = Opinion.find params[:opinion_id]
  @like = @opinion.likes.build(user: current_user)
  respond_to do |format|
      if @like.save
        format.html { redirect_to opinion_path(@like.opinion),
         notice: ...' }
end

そして、ライクが保存されたら元居たオピニオンページにリダイレクトするようにしましょう。

課題

ユーザーも同様にビューを実装しましょう。

無料ビデオ講座のお知らせ

Skillhub [スキルハブ]では無料の動画講座を多数公開しています。他校だと数万円するような講座が無料で受講できます。

無料講座一覧を見る

×