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

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

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

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

JavaScript

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

Ajax

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

Q&A

解決済

1回答

2836閲覧

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

tmrk77

総合スコア1

Ruby on Rails

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

JavaScript

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

Ajax

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

0グッド

0クリップ

投稿2020/08/16 05:15

編集2020/08/17 00:47

前提・実現したいこと

rails,jsでいいね機能を非同期で実装しようとしています。
詳細ページでは実装できるようになったのでトップページでも実装しようとした。その時のエラーを解決したいと思っています。何か分かりましたら回答よろしくお願いします。
<現在できている事>
商品詳細ページでは非同期でいいね機能を実装できています。
<前提>
詳細ページでは「お気に入り」という文字を表示されているがトップページでは表示させない。
<解決したい事・できるようにしたい事>
トップページからログインしているユーザーであれば非同期でいいね「登録」「解除」できるようにしたい。

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

イメージ説明

該当のソースコード

・ルーティング

routes

1中略 2 resources :products do 3 4 resources :favorites, only: [:create, :destroy] 5 end

・コントローラー

products

1def index 2 @products = Product.includes(:photos).order(created_at: :desc).limit(5) 3end 4 5def show 6 @products = Product.all 7 if @product == @products.first 8 @next_product = Product.next_search(@product) 9 elsif @product == @products.last 10 @prev_product = Product.prev_search(@product) 11 else 12 @prev_product = Product.prev_search(@product) 13 @next_product = Product.next_search(@product) 14 end 15 @grandchild = Category.find(@product.category_id) 16 @child = @grandchild.parent 17 @parent = @child.parent 18 @parent_category_products = @products.select { |product| product.category.root.name == @parent.name } 19 @user = current_user 20 Payjp.api_key = ENV['PAYJP_PRIVATE_KEY'] 21 @card = CreditCard.find_by(user_id: current_user) 22 if user_signed_in? 23 @favorite = Favorite.find_by(user_id: current_user.id, product_id: params[:id]) 24 end 25 end

favorites

1class FavoritesController < ApplicationController 2 3 def create 4 @favorite = Favorite.create(user_id: current_user.id, product_id: params[:product_id]) 5 @favorites = Favorite.where(product_id: params[:product_id]) 6 @product = Product.find(params[:product_id]) 7 end 8 9 def destroy 10 @favorite = Favorite.find_by(user_id: current_user.id, product_id: params[:product_id]) 11 @favorite.destroy 12 @favorites = Favorite.where(product_id: params[:product_id]) 13 @product = Product.find(params[:product_id]) 14 end 15end

・モデル

product

1中略 2 has_many :favorites, dependent: :destroy 3 has_many :favorite_users, through: :favorites, source: :user 4 5 def favorite_user(user_id) 6 favorites.find_by(user_id: user_id) 7 end

user

1中略 2 has_many :products, dependent: :destroy 3 has_many :favorites, dependent: :destroy 4 has_many :favorite_products, through: :favorites, source: :product 5 6 def already_favorited?(product) 7 self.favorites.exists?(product_id: product.id) 8 end

favorite

1class Favorite < ApplicationRecord 2 belongs_to :user 3 belongs_to :product 4 5 validates_uniqueness_of :product_id, scope: :user_id 6end

・ビュー
products/index.html.haml

index

1#products-favorites 2 = render "favorites/products_favorite", locals: {product: @product}

products/show.html.haml

show

1#favorites 2 = render "favorites/favorite", locals: {product: @product}

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

- if user_signed_in? - if current_user.already_favorited?(product) = link_to product_favorite_path(product, @favorite), method: :delete, remote: true do %i.fas.fa-star お気に入り = product.favorites.count - else = link_to product_favorites_path(product), method: :post, remote: true do %i.far.fa-star お気に入り = product.favorites.count - else = icon('fa', 'star') お気に入り = product.favorites.count

favorites/_products_favorite.html.haml

- if user_signed_in? - if current_user.already_favorited?(@product) = link_to product_favorite_path(@product, @favorite), method: :delete, remote: true do %i.fas.fa-star = @product.favorites.count - else = link_to product_favorites_path(@product), method: :post, remote: true do %i.far.fa-star = @product.favorites.count - else = icon('fa', 'star') = @product.favorites.count

・jsファイル
favorites/create.js.haml、destroy.js.haml

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

試したこと

@product.present?を試すと返り値としてfalseが、@products.present?を試すと返り値としてtrueが帰ってきた。部分テンプレートの@productを@productsに変更したが別のエラーが出た。

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

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

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

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

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

guest

回答1

0

ベストアンサー

詳細ページと同じようにレンダリング使用としていますがこの@productはどこで定義していますか?

- @products.each do |product| = render partial: "favorites/favorite", locals: {product: product}

上記のような内容になると思います。?(このコードが正しいかは分かりません)
indexアクションでProductモデルのデータを取得しeachでループ処理を行いshow.html.hamlと同じようにレンダリングする形です。

投稿2020/08/16 12:54

編集2020/08/16 22:03
nasuk47

総合スコア311

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

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

tmrk77

2020/08/16 13:22

ご回答ありがとうございます。@productは確かに定義していませんでした。ありがとうございます。提案されたコードを試しましたが、やはり同じエラーでidが取得できていない感じでした。また、productsコントローラーに @product = Product.find(params[:id]) を試してみましたが、これもidが取得されていませんでした。 - @products.each do |product|を試した時のターミナルでは、 Completed 500 Internal Server Error in 235ms (ActiveRecord: 14.6ms | Allocations: 306131) ActionView::Template::Error (undefined method `id' for nil:NilClass): 1: - if user_signed_in? 2: - if current_user.already_favorited?(@product) 3: = link_to product_favorite_path(@product, @favorite), method: :delete, remote: true do 4: %i.fas.fa-star 5: = @product.favorites.count と表示していました。またもう一度解決方法を考えてみます。本当にご回答ありがとうございました。また何か分かったなら教えていただけるとありがたいです。またのご回答心待ちしています。
nasuk47

2020/08/16 13:28

回答に追記しました @productをproductに変更してみてください。
tmrk77

2020/08/16 13:37

ありがとうございます。変更してみたところ、下記のようなエラーが出ました。だから@productのままなのか、productのまま他のどこかを直す必要があるかもしれないと思っていますがこの解釈は間違っていますか?ご指摘があれば修正しますのでまたのご回答よろしくお願いします。 https://i.gyazo.com/68f483781ab7670c6a3234565586cd8f.png
tmrk77

2020/08/16 14:26

なるほどです。ありがとうございます。修正しました所、下記のエラーが表示されました。urlが間違っていると思い、rails routesで確かめてみた所、間違いありませんでした。productのidは取得することができましたが、今度はfavoritesのidを取得できていないみたいです。productsコントローラーのindexアクションに@favoriteを定義してlocalsの中身やurlの引数にもfavoriteの記述を増やしてみましたが、同じエラーが出てしまいました。何度もすみません。 https://i.gyazo.com/f2b1952ffae17202ed4b294f98bccad2.png
nasuk47

2020/08/16 22:11

現状のコードを質問に反映させてください。お願いします。 ProductsControllerのshowアクションだとおそらく@productを定義していると思いますがどのように定義しているのかを確認する必要があるため後基本的にコードは中略して書かないようにお願いします。
tmrk77

2020/08/17 09:31

あれ、すみません。エラー解決できていました。何度もご回答していただき、最後まで質問に答えてくれてありがとうございました!
nasuk47

2020/08/17 09:52

よかったです。引き続き学習頑張ってください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問