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

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

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

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

JavaScript

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

1回答

1317閲覧

NoMethodError undefined method `favorite_user' for nil:NilClass いいね機能

tmrk77

総合スコア1

Ruby on Rails 6

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

JavaScript

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2020/08/13 10:01

編集2020/08/13 10:22

前提・実現したいこと

フリマサイト的なのを作成しています。
まず、ほとんどの実装は完成しています。
今は、出品した商品にいいね機能を実装しようとしています。
まず、同期通信でいいね機能を実装できるようにして成功しました。
次に、商品詳細ページでいいねを非同期通信できるようにして成功しました。
最後にトップページに出品商品の一覧表示があるのですが、サインインしていたらここでも非同期でいいねできるように実装しています。
その実装中に下記のようにエラーが表示されました。

発生している問題・エラーメッセージ

イメージ説明

該当のソースコード

######コントローラー
・product_controller.rb

def index @products = Product.includes(:photos).order(created_at: :desc).limit(5) end 中略

・favorite_controller.rb

class FavoritesController < ApplicationController def create @favorite = Favorite.create(user_id: current_user.id, product_id: params[:product_id]) @favorites = Favorite.where(product_id: params[:product_id]) @product = Product.find(params[:product_id]) end def destroy @favorite = Favorite.find_by(user_id: current_user.id, product_id: params[:product_id]) @favorite.destroy @favorites = Favorite.where(product_id: params[:product_id]) @product = Product.find(params[:product_id]) end end

######テーブル
・favorite

class CreateFavorites < ActiveRecord::Migration[6.0] def change create_table :favorites do |t| t.references :user, null: false, foreign_key: true t.references :product, null: false, foreign_key: true t.timestamps t.index [:user_id, :product_id], unique: true end end end

######モデル
・user.rb

中略 has_many :products, dependent: :destroy has_many :favorites, dependent: :destroy has_many :favorite_products, through: :favorites, source: :product def already_favorited?(product) self.favorites.exists?(product_id: product.id) end

・product.rb

中略 has_many :favorites, dependent: :destroy def favorite_user(user_id) favorites.find_by(user_id: user_id) end

・favorite.rb

class Favorite < ApplicationRecord belongs_to :user belongs_to :product validates_uniqueness_of :product_id, scope: :user_id end

######ビュー
・products/index.html.haml

中略 #product_favorites = render "favorites/product_favorite", locals: {product: @product}

・products/show.html.haml

中略 #favorites = render "favorites/favorite", locals: {product: @product}

######部分テンプレート
・favorites/_favorite.html.haml

- if user_signed_in? - if current_user.already_favorited?(@product) = link_to product_favorites_path(@product), method: :delete, class: "btn_font-awesome", remote: true do %i.fas.fa-heart お気に入り = @product.favorites.count - else = link_to product_favorites_path(@product), method: :post, class: "btn_font-awesome", remote: true do %i.far.fa-heart お気に入り = @product.favorites.count - else %i.fas.fa-heart お気に入り = @product.favorites.count

・favorites/_product_favorite.html.haml

- if user_signed_in? - if @product.favorite_user(current_user.id) aiueo = link_to product_favorites_path(@product), method: :delete, class: "btn_font-awesome", remote: true do %i.fas.fa-heart = @product.favorites.count - else = link_to product_favorites_path(@product), method: :post, class: "btn_font-awesome", remote: true do %i.far.fa-heart = @product.favorites.count - else %i.fas.fa-heart = @product.favorites.count

######jsファイル
・favorites/create.js.haml

$("#favorites").html("#{j(render partial: "favorites/favorite", locals: { product: @product })}"); $("#product_favorites").html("#{j(render partial: "favorites/product_favorite", locals: { products: @products })}");

・favorites/destroy.js.haml

$("#favorites").html("#{j(render partial: "favorites/favorite", locals: { product: @product })}"); $("#product_favorites").html("#{j(render partial: "favorites/product_favorite", locals: { products: @products })}");

試したこと

多分余分なコードも掲載していると思います。商品詳細ではできていたので一応そのコードも載せておきました。一覧画面ではできていません。コメントアウトなどして試すと、部分テンプレートはしっかり機能していました。しかしコメントアウトを外すとエラーが出てしまいました。いいね機能の非同期通信ができているshowの時と同じようにしたつもりでしたができないので、何かわかる人がいたら教えていただけるとありがたいです。よろしくお願いします。

ちなみに、詳細ではマーク、いいね数、"お気に入り"という文字
一覧では、マーク、いいね数だけでマークをクリックするといいねを付け加えたり削除できたりの実装をしようと思っています。

改めてよろしくお願いします。

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

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

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

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

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

guest

回答1

0

product_controller.rb からは @products と複数形の変数で渡しているのに products/index.html.haml では @product と単数形の変数を扱っています。@product は定義されていなくて nil なので undefined method 'favorite_user' for nil:NilClass が発生しています。

products/index.html.haml を以下のように書き換えたら動作するのではないでしょうか。

ruby

1中略 2#product_favorites 3 = render "favorites/product_favorite", collection: @products, as: "product"

投稿2020/08/13 15:25

saoyagi2

総合スコア210

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

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

tmrk77

2020/08/13 15:40 編集

回答ありがとうございます。変更してみましたが、変わらず、同じエラーでした。また何か分かりましたら些細なことでも教えていただけるとありがたいです。本当にありがとうございます。よろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問