Rails初心者によるはじめてのWebアプリ制作日記 Vol.5 -いいね機能編-

2018-05-22

前回、ログイン機能までできましたので次はいいね機能を付けます
いいねボタンがあるとよりSNSっぽいですね!

Ajaxの勉強

いいね機能のやり方もprogateにあったから真似すれば簡単にできそう〜と、余裕をこいていた私。
そんな私にメンターが「いいね機能なら、Ajaxを使う必要がありますね」と。

(Ajax… 良く名前は目にするけど、実は良くわかっていないやつだ…)

そんな訳で、Ajaxとは?から教えて頂きました。

Ajaxとは?

正式名称は「Asynchronous JavaScript + XML」
Asynchronousは「非同期」という意味で、非同期通信がキーワードです。

うまく説明はできないので、Ajaxについて詳しく知りたい方は、ググって下さい。笑

Ajaxを使うことで、いいねボタンを押した時に画面全体を再読み込みしなくても、ボタンだけが押した状態に変わるってわけですね!
確かにSNSでボタンを押すたびに画面全部を読み込みされたら、嫌ですもんね〜

勉強方法

AjaxはJQueryを使うのがやりやすいとのこと!
それにはJQueryの知識が必要になり、JQueryはJavaScriptのプラグインですので、下記の順番で勉強するのがいい流れと教えてもらいました。

1. JavaScript
2. JQuery
3. Ajax

幸い、JavaScriptとJQueryは業務経験がありましたので、ドットインストールを使用して忘れたJQueryの復習を軽くしました。

progateを使用するのも良いですが、復習とかちょっと思い出す程度ならドットインストールの方が動画で短時間で確認できるのですごく良いです!方法は文法の確認なので動画を見るだけ。3分の動画を20本なので1時間弱で全て見終わりました!!

おかげで半年以上触ってなくて忘れていたJQueryの文法を思い出しましたよ。
プログラミングも言葉ですから、使い続けないと忘れるんですよね〜

復習も終わったのでいよいよAjax。
Ajaxの書き方はざっくりこんな感じですかね〜
 

$(function(){
  $.ajax({
    //通信方法(どのサーバーにどうやって[get,postなど]通信するか)
  }).done(function(data) {
    //データを受け取った後の処理
  });
});

Ajaxは実際に書いて動かして見るのが一番良いので、メンターに口頭で指示をもらいながらサンプルコードを書いて見ました。
サンプルコードはRESASというAPIを使用して、都道府県を選択すると選択した都道府県別の市町村名を取得できるというもの。住所登録フォームとかに良くあるやつです。



ページを開いたら左のセレクトボックスにAPIから取得した都道府県名が入ります。

都道府県を選択したら、右のセレクトボックスに選択した都道府県の市町村名が入る仕組みです。

これで何となくAjaxの仕組みがわかったので、いいねボタンに応用していきます

 

いいねボタンの作成

likeモデル、コントローラーの作成

Ajaxを使用すること以外はProgataにある方法が使えますので、RailsのレッスンⅩを真似をしてlikeモデルとコントローラーを作成しました。
Font Awesomeのハートボタンも取り入れます!

ちなみに私はProgateのレッスンと同じではなく少しアレンジをして、いいねしていない時はグレーの線だけのハート、いいねしたらピンクの全塗りハートになるようにしました(Twitterを真似した)

出来上がった画面がこちら

いいねする前

いいねした後

ユーザーページにはいいねした一覧も作ります。
右側の列がいいねした一覧です(Progateみたいにタブ分けにしたかったけど、後回しにした。笑)

もちろん、これだけでも十分使えますが、ここにAjaxを入れて行きます!

JQueryの導入

Ajaxを使用するには、まずRailsでJQueryを使用できるようにしなくてはいけません。
このページがわかりやすかったので参考にさせて頂きました。

gemを入れて

gem 'jquery-rails'

bundle installする

$ bundle install

あとは上記サイトを参考にJQueryが有効になっていること確認したので、JQueryの導入は完了です。

Ajaxの導入

やっと本題です。
ちなみにJqueryの導入までは自力でスムーズに行きましたが、実際、いいねボタンにAjaxってどうすればいいんだ?と初心者はお手上げになりましたので…ここからはメンターに教えてもらいながら作りました。

Ajaxは初心者にはなかなかレベルが高かったです…

JQueryで書く処理をまとめると以下のようになります。

・いいねボタンを押したときに、Likesコントローラーのceateメソッドを呼ぶ。
・createメソッドはLikeテーブルにデータをinsertする。
・createメソッドはJson形式でデータを渡す。
・Jsonデータを受け取ったら、いいねボタンの色を変える。

・いいねされているボタンを押したときは、Likesコントローラーのdestroyメソッドを呼ぶ。
・destroyメソッドはLikeテーブルからデータをdereteする。
・destroyメソッドはJson形式でデータを渡す。
・Jsonデータを受け取ったら、いいねボタンの色を変える。



さて、まずはコントローラーにJson形式でデータを渡すように改良します。
 

  def create
    @like=Like.new(
      user_id: @current_user.id,
      post_id: params[:post_id]
    )
    @like.save

    like = {'user_id' => @like.user_id, 'post_id' => @like.post_id}
    render json: like
  end

render json: xxxx
とすることでコントローラーが呼ばれた際に、Json形式でデータを渡します。



Ajaxでこのcreateコントローラーを呼ぶように処理を書きます。
※とりあえず、これからやるところは日本語で書いています。
 

$(function(){
  $('いいねボタン').on('click',function(){
   $.ajax({
        url: '/likes/'+ ポストID + '/create',  //←createメソッドのURL
        type:'POST',
     }).done(function(data){
       //ボタンの色を変える処理
     });
   });
});

createメソッドを呼ぶにはポストIDが必要になるので、ビューから渡してあげる必要がありました。

では、ビューを改良します。

<% if Like.find_by(user_id: @current_user.id, post_id: @post.id) %>
  <!-- いいねされている時 -->
     <a href="javascript:void(0)" post_id="<%= @post.id %>" class="like_btn">
          <i btn="like" class="fas fa-heart like"></i>
     </a>
<% else %>
 <!-- いいねされていない時 -->
     <a href="javascript:void(0)" post_id="<%= @post.id %>" class="like_btn">
          <i btn="unlike" class="far fa-heart unlike"></i>
     </a>
<% end %>

post_id=”<%= @post.id %>”
という風に、属性を作成することで、Jquery側に値を渡せるようになります。

post_id属性の値をcreateメソッドのURLに入るようにJqueryを編集しました。

$(function(){
  $('.like_btn').on('click',function(){
    var $likeBtn = $(this);
    var $postId = $likeBtn.attr("post_id");  //post_id属性の値を取得

    $.ajax({
      url: '/likes/'+ $postId + '/create',  //←createメソッドのURL
      type:'POST',
    }).done(function(data){
      //ボタンの色を変える処理
    });
  });
});

だいぶ形にになったけど、これではいいねを取り消す処理がないので、destroyメソッドも呼べるようにします。でも、変わるのはメソッドを呼び出すURLが変わるだけなので、条件分岐でURLの中身を変えるようにするとスッキリしていいだろうと教えてもらったので、取り入れます!

ちなみにifで書いてもいいけど、ifの中身が1行で済む場合は三項演算子を使うとよりスッキリ書けると教えてもらったので、それも取り入れてみました。

※三項演算子
「条件式 ? trueのときの処理 : falseの時の処理」
 

var $like = $(this).find('i');
var $btnClass = $like.attr("class");
var url = $btnClass == 'far fa-heart unlike' ? '/create' : '/destroy';

$.ajax({
   url: '/likes/'+ $postId + url,

これで、’far fa-heart unlike’(いいねしていないときのclass)がある時はcreateメソッド、ない時はdestroyメソッドを呼ぶようになります。



ここまできたら、あとは押したボタンに応じて色を変える処理を入れて完成です!!!

$(function(){
  $('.like_btn').on('click',function(){
    var $likeBtn = $(this);
    var $postId = $likeBtn.attr("post_id");
    var $like = $(this).find('i');
    var $btnClass = $like.attr("class");

    var url = $btnClass == 'far fa-heart unlike' ? '/create' : '/destroy';

    $.ajax({
      url: '/likes/'+ $postId + url,
      type:'POST',
    }).done(function(data){
      if($like.hasClass('unlike')){
        $like.removeClass('far unlike').addClass('fas like');
      }else{
        $like.removeClass('fas like').addClass('far unlike');
      }
    });
  });
});

ここまで来るのに結構かかりましたが、これで無事に完成しました!
見た目は変わっていませんが、いいねボタンを押してもボタン以外は再読み込みしたりしません。

この、いいねボタンを実装したところで、スクールの3ヶ月の期間が終了しました。アプリに必要な機能はだいぶ勉強できたかなと思います!

ちなみにここまでできた段階で、このアプリは転職活動の際に作品として見せるのに使いました。未完成ですけど、評価を頂けた企業様もありましたので見せて良かったと思います。

さて、ここからは自力で頑張ります!!!
残すはフォロー機能とデザインなどのフロント周りです。

では、続きは次回