質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

4147閲覧

Railsの非同期通信でいいね機能が反映されるようにしたい

graphic-ocean

総合スコア12

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2017/02/28 11:49

●実現したいこと

現在、ユーザーの作品を投稿できるInstagramのようなサイトを作成しています。
その中で、作品に「いいね」が押せるように機能を追加しようとしているのですが、「いいねボタン」を押しても、リロードしないと結果が反映されない状態が出ています。

●質問

以下エラー文にあるart.like_userのartがnilになっていることは、何となく感じているのですが、その対処法がわからず悩んでおります。

●「いいねボタン」を押した際に起きているエラー

ActionView::Template::Error (undefined local variable or method `art' for #<#<Class:0x007ff54d1973b0>:0x007ff54b9f6f08> Did you mean? arts art_url @arts): 1: <% if user_signed_in? %> 2: <% if art.like_user(current_user.id) %> 3: <%= button_to art_likes_path(like, art_id: art.id), method: :delete, id: "like-button", remote: true do %> 4: <%= image_tag("icon_red_heart.svg") %> 5: <span> app/views/likes/_like.html.erb:2:in `_app_views_likes__like_html_erb___1033727092812393927_70345769537660' app/views/likes/create.js.erb:1:in `_app_views_likes_create_js_erb__3536096750636237475_70345756223260'

●各ファイルの状態 index.html.erb

<% @arts.each do |art| %> <div class="contents col-md-3 clearfix"> <div class="art_image"> <%= image_tag art.image.url %> </div> <span class="user_data">投稿者:</span><%= art.user.nickname %> <% if user_signed_in? && current_user.id == art.user_id %> <ul class="more_list"> <li> <%= link_to '編集', "/arts/#{art.id}/edit", method: :get %> </li> <li> <%= link_to '削除', "/arts/#{art.id}", method: :delete %> </li> </ul> <% end %> <div class="like"> <%= render partial: 'likes/like', locals: { art: art, arts: @arts, likes: @likes, like: @like } %> </div> </div> <% end %>

●各ファイルの状態 _like.html.erb

<% if user_signed_in? %> <% if art.like_user(current_user.id) %> <%= button_to art_likes_path(like, art_id: art.id), method: :delete, id: "like-button", remote: true do %> <%= image_tag("icon_red_heart.svg") %> <span> <%= art.likes_count %> </span> <% end %> <% else %> <%= button_to art_likes_path(art), id: "like-button", remote: true do %> <%= image_tag("icon_heart.svg") %> <span> <%= art.likes_count %> </span> <% end %> <% end %> <% else %> <%= image_tag("icon_heart.svg") %> <span> <%= art.likes_count %> </span> <% end %>

●各ファイルの状態 routes.rb

Rails.application.routes.draw do devise_for :users resources :users, only: [:show, :edit, :update] root to: "arts#index" resources :arts, only: [:index, :new, :create, :show, :edit, :update, :destroy] do resources :likes, only: [:create, :destroy] end end

●各ファイルの状態 likes_controller

class LikesController < ApplicationController def create @like = Like.create(user_id: current_user.id, art_id: params[:art_id]) @likes = Like.where(art_id: params[:art_id]) @arts = Art.all end def destroy like = Like.find_by(user_id: current_user.id, art_id: params[:art_id]) like.destroy @likes = Like.where(art_id: params[:art_id]) @arts = Art.all end end

●各ファイルの状態 create.js.erb

$("#like-button").html("<%= j(render partial: 'likes/like', locals: { arts: @arts, likes: @likes, like: @like}) %>");

●各ファイルの状態 destroy.js.erb

$("#like-button").html("<%= j(render partial: 'likes/like', locals: { arts: @arts, likes: @likes }) %>");

●各ファイルの状態 art.rb

class Art < ActiveRecord::Base belongs_to :user mount_uploader :image, ImageUploader has_many :likes, dependent: :destroy def like_user(user_id) likes.find_by(user_id: user_id) end end

各ファイルの状態 like.rb

class Like < ActiveRecord::Base belongs_to :art, counter_cache: :likes_count belongs_to :user end

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

とりあえず、これでいいんじゃないですかね?

ruby

1class LikesController < ApplicationController 2 def create 3 @like = Like.create(user_id: current_user.id, art_id: params[:art_id]) 4 @likes = Like.where(art_id: params[:art_id]) 5 @art=Art.find(params[:art_id]) 6 @arts = Art.all 7 end 8 9 def destroy 10 like = Like.find_by(user_id: current_user.id, art_id: params[:art_id]) 11 like.destroy 12 @likes = Like.where(art_id: params[:art_id]) 13 @art=Art.find(params[:art_id]) 14 @arts = Art.all 15 end 16end

create.js.erb

ruby

1$("#like-button").html("<%= j(render partial: 'likes/like', locals: {art: @art,arts: @arts, likes: @likes, like: @like}) %>");

ruby

1$("#like-button").html("<%= j(render partial: 'likes/like', locals: {art: @art, arts: @arts, likes: @likes }) %>");

余力があるなら

ruby

1class LikesController < ApplicationController 2 def create 3 @art=Art.find(params[:art_id]) 4 @like = @art.likes.create(user_id: current_user.id) 5 @likes =@art.likes 6 @arts = Art.all 7 end 8 9 def destroy 10 @art=Art.find(params[:art_id]) 11 like = @art.likes.find_by(user_id: current_user.id) 12 like.destroy 13 @likes =@art.likes 14 @arts = Art.all 15 end 16end

意味を考えつつこのようなリファクタリングをしてみては?

投稿2017/02/28 12:10

moke

総合スコア2241

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

graphic-ocean

2017/02/28 14:11

mokeさん 早速ご教示頂きまして、誠にありがとうございます。 上記方法を試してみたところ、非同期通信で反映されるようになりました。 「余力があるなら」とお教え頂いた分についても、一度試してみたいと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問