Help us understand the problem. What is going on with this article?

お気に入り(いいね)機能をajaxで投稿のindexページにつけてみる。(ajaxがメインです)

More than 1 year has passed since last update.

環境
Rails 5.1.1
Ruby 2.3.0

前提条件

userテーブルに紐づいたblogテーブルがあること(1:多)。
userとblogの中間テーブルのfavoriteがあること(多:多)
お気に入り機能をすでに実装済みであること。(user_id,blog_idの値をレコードをfavoriteテーブルに保存する処理)

流れ

1、送信方法をdata-remote: trueにする。
2、お気に入りボタンを変更する。
3、favorites_controllerをJSを対応した設定にする。
4,JSファイルを作成し、indexページのお気に入り部分を動的に処理する記述をする。

1

views/favorites/_favorite.htm.erb

<% favorite = current_user.favorites.find_by(blog_id: blog.id) %>
<% if favorite.present? %>
  <%= link_to favorite_path(id: favorite.id), method: :delete, remote: true, class: "glyphicon glyphicon-heart", style:"color: red"do %><% end %>
<% else %>
  <%= link_to favorites_path(blog_id: blog.id),method: :post, remote: true, class: "glyphicon glyphicon-heart-empty" do%><% end %>
<% end %>

remote: tureの送信方法にしてください。Ajaxを使用するため。このファイルはindex.html.erbに描画(レンダリング)されるお気に入りボタンです。

2

views/blogs/index.html.erb

<%= @blogs.each do |blog| %>

~省略

<div id="favorite_btn_<%= blog.id %>">
  <%= render partial: "favorites/favorite", locals: {blog: blog} %>
</div>

<% end %>

ここのidが後々のJSで要素を取得するターゲットになります。idの末尾の<%= blog.id %>の記述は、どの投稿かを区別するため。renderにより_favorites.html.erbを描写(レンダリング)しています。 locals: {blog: blog}はレンダリング元にローカル変数を渡す設定です。locals: {ローカル変数: 代入したい値}

3

controllers/favorites_controller

def create
    @favorite = current_user.favorites.create(picture_id: params[:blog_id])
    @blog = Blog.find(params[:blog_id])

    respond_to do |format|
    format.js {render :template => "blogs/index",locals: { favorite: @favorite, blog: @blog} } 
    end
end

repond_to do |format|によりファイル名.js.erbになってものを探してきてくれる。
renderに:templateオプションで別のコントローラのviewをレンダリングできる。view/blogs/create.js.erbを探しに行ってくれる。http://railsdoc.com/references/render
これしないとview/favorites/create.jsを探しちゃいます。あとlocalsでレンダリング後に使うローカル変数の設定も忘れずに。

view/blogs/create.js.erb

$("#favorite_btn_<%= favorite.blog_id %>").html("<%= j(render 'favorites/favorite',{favorite: favorite, blog: blog})%>");

1の_favorite.html.erbにレンダリングしてます。レンダリング先でお気入りボタンの条件分岐の処理(お気に入りされいるか否か?)をしているので、ここでもローカル変数の設定。JSだとlocalsとは書かないみたいなので、記述の違いに注意。
これで完成。お気入りのボタンはbootstrapのglyphicon使いました。

結果イメージ

https://gyazo.com/bcc77e5dc4e8fb83f1fcdd34a1c531e0

2ヶ月前のメモしたものを書いてるので、色々と忘れてますが、何かおかしなところがありましたらお申し付けください。素人なので間違っていたり回答が遅いかもしれませんが、その辺はご容赦くださいませ。

shh-nkmr
海外のパン屋からエンジニアへ。
maplesystems
エンジニアの未来を考えるサービスを開発・運営するスタートアップ
http://www.maplesystems.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした