LoginSignup
4
0

More than 5 years have passed since last update.

タイムラインでいいね機能をつけたい!!~後編~

Last updated at Posted at 2018-05-04

前説

ここ最近サボっていたので、気を取り直して書いていきます。

非同期通信

https://qiita.com/networkyohan69/items/40cf567880557148d8f4
上記の記事は同期通信を行った時のいいね!取得です。こちらでいいねボタンを押す▶︎リロード▶︎データベースに保存までを実装できました。

いくつか実装パターンがあると思いますが、分類分けしてみました。

Aパターン、Ajaxでゴリゴリ

スクリーンショット 2018-05-04 8.45.02.png

https://qiita.com/yukisaibai/items/0a84e8c02f423faa7891
上記の方はゴリゴリ書いてらっしゃいます。

メリット

  • ajaxの勉強になる
  • 応用性が効く

デメリット

  • 学習コスト

新しいものにチャレンジしたい人におすすめ

Bパターン、Railsでゴリゴリ

スクリーンショット 2018-05-04 8.39.20.png

僕はこちらで書いてました。

メリット

  • railsをもっと勉強したい
  • railsやっている人ならこちらの方が早い?

デメリット

  • 応用性

コード

_product.html.erb
<li id="product-<%= a_product.id %>" class="collection-item" >
  <span class="timestamp"></span>
  <div class="like-button-<%= a_product.id %>">
    <%= render 'products/likes' , a_product: a_product %>
  </div>
</li>
_like.html.erb
<span class="like">
  <% if current_user %>
    <% if a_product.user_exist?(current_user) %>
        <div class = "action">
      <!--すでにいいね!を押してるかどうかの判定 それに応じて画像を変更している-->
           <%= form_for [a_product,@like],url: product_like_path(a_product.id,@like.id),method: :delete, remote: true do |f| %>
            <%= image_submit_tag("like.png",class: "main_img" )%>
           <% end %>
        </div>

    <% else %>
        <div class = "action">
        <!--, url: product_likes_path(a_product.id)はpathが複数形なのでなくても良い-->
          <%= form_for [a_product, @likes], method: :post, remote: true do |f| %>
            <%= image_submit_tag("unlike.png",class: "main_img" ) %>
          <% end %>
      </div>
    <% end %>
  <% end %>
</span>

form_for,remote:trueで非同期通信を用いてパスやメソッドを投げている。

create.js
$(".like-button-<%= @product.id %>").html("<%= j(render partial: 'products/likes', locals: { a_product: @product }) %>")

_product.html.erbのclass名を指定して、render先のhtml.erbを読み込んでいる。

destroy.js
$(".like-button-<%= @product.id %>").html("<%= j(render partial: 'products/likes', locals: { a_product: @product }) %>")

_product.html.erbのclass名を指定して、render先のhtml.erbを読み込んでいる。

Bパターンの流れ

  • いいね押す
  • form_for,remote:trueでデータベースに非同期で変更
  • (いいね画像の変更をしてほしい)
  • 非同期で_like.html.erbを読み込む
  • データベースの情報が反映されていいねの切り替えがうまくできた

Aパターンのコードでは画像の切り替えを行っているが、Bパターンではデータベースの情報を元に非同期でパーションされた部分テンプレートを読み込んでいるという感じですね。

苦戦原因

  • どのいいねを押したか、固有のidを取得できない
    • $(".like-button-<%= @product.id %>")とすることによってどのいいねボタンのclassを読み込むのか明確化させる
    • 最初、なぜかidで指定していた(固有のproduct.idを持つので別にいいが、念のため)
  • javascriptが動かない
    • render先の_like.html.erbを読み込むはずが、対象の_like.html.erb内のクラスを指定していたので無限ループ状態になっていた。

スクリーンショット 2018-05-04 9.11.29.png

終わりに

気づいたらBパターンで書いていた。
- Railsのform_forの使い方を見つめ直せたのでよかった。 
- rubyがしっかり書けていないなあと猛省。
- javascriptでしっかりコードを書いていきたいなあと思いました。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0