前提・実現したいこと
Ruby on rails 初心者です。
現在、ECサイトの構築を行っており、つまずいたのはセッション機能を用いた「カートにいれる」処理です。
参考にしているサイト「https://qiita.com/kenzo-ta/items/b45994c5f3fdd87b6c50」
発生している問題・エラーメッセージ
エラーメッセージはでず、「carts_controller」の「create」アクションで@cart_item.saveされず、elseの方に回ってしまいます。 show.html.erbの「カートに追加」ボタンを押下すると、「application_controller」「carts_controller」を経由して、 cartsテーブル(user_idカラム)/cart_itemsテーブル(quantity/product_id/cart_idカラム)にデータが入る仕組み なのですが、両テーブルともにデータが入りません。
該当のソースコード
(app/vies/products/show.html.erb) <div class="cart"> <%= form_for(:session, url: carts_path) do |f|%> <%= f.label :quantity, "数量"%> <%= f.select :quantity, [1,2,3,4,5,6,7,8,9,10]%> <%= f.submit "カートに追加", class:"btn cart_btn" %> <% end %> </div>
(app/controllers/carts_controller) class CartsController < ApplicationController before_action :set_line_item, only: [:create, :destroy] before_action :set_user before_action :set_cart def create @cart_item = @cart.cart_items.build(product_id: params[:product_id]) if @cart_item.blank? if @cart_item.save redirect_to current_cart else redirect_to products_path end end def destroy @cart.destroy redirect_to current_cart end private def set_user @user = current_user end def set_line_item @cart_item = current_cart.cart_items.find_by(product_id: params[:product_id]) end def set_cart @cart = current_cart end end
(app/controllers/application_controller)一部記載 def current_cart if session[:cart_id] current_cart = Cart.find_by(id: session[:cart_id]) session[:cart_id] = current_cart.id current_cart else current_cart = Cart.create(user_id: current_user.id) session[:cart_id] = current_cart.id current_cart = Cart.find_by(id: session[:cart_id]) current_cart end end
(app/models/cart_item.rb) class CartItem < ApplicationRecord belongs_to :product belongs_to :cart belongs_to :user end
(app/models/cart.rb) class Cart < ApplicationRecord has_many :cart_items end
(app/models/user.rb)一部記載 has_many :carts
試したこと
アソシエーション系の問題ではないかと思い、has_manyやbelong_toを再確認した。
補足情報(FW/ツールのバージョンなど)
ruby 2.6.6
rails '~> 5.2.4', '>= 5.2.4.3'
編集後/最新コード
(app/vies/products/show.html.erb) <div class="cart"> <%= form_for(:session, url: cart_items_path) do |f|%> <%= f.label :quantity, "数量"%> <%= f.select :quantity, [1,2,3,4,5,6,7,8,9,10]%> <%= f.hidden_field :product_id, value: @product_info.id %> ←★変更点 <%= f.submit "カートに追加", class:"btn cart_btn" %> <% end %> </div>
(app/controllers/cart_items_controller)←★変更点(carts_controller.rbの内容を全てcart_items_controller.rb)に移動 class CartItemsController < ApplicationController before_action :set_line_item, only: [:create, :destroy] before_action :set_user before_action :set_cart def create @cart_item = @cart.cart_items.build(product_id: session[:product_id]) if @cart_item.blank? ←★変更点(session[:product_id]) if @cart_item.save! ←★変更点 redirect_to current_cart else redirect_to products_path end end def destroy @cart.destroy redirect_to current_cart end private def set_user @user = current_user end def set_line_item @cart_item = current_cart.cart_items.find_by(product_id: params[:product_id]) end def set_cart @cart = current_cart end end
(app/controllers/application_controller)一部記載 def current_cart if session[:cart_id] current_cart = Cart.find_by(id: session[:cart_id]) session[:cart_id] = current_cart.id current_cart else current_cart = Cart.create(user_id: current_user.id) session[:cart_id] = current_cart.id current_cart = Cart.find_by(id: session[:cart_id]) current_cart end end
(app/models/cart_item.rb) class CartItem < ApplicationRecord belongs_to :product belongs_to :cart belongs_to :user end
(app/models/cart.rb) class Cart < ApplicationRecord has_many :cart_items belongs_to :user ←★変更点 end
(app/models/user.rb)一部記載 has_many :carts
(app/controllers/products_controller.rb)一部記載 def show @product_info = Product.find_by(id: params[:id]) @product_images = @product_info.images end
発生している問題・エラーメッセージ
以下のようなエラーとなりました。 cartテーブルにはデータ(current_user.id=user_id)が入りました。 ただ、cart_itemsのテーブルにはデータが登録されませんでした。 Validation failed: Product must exist Extracted source (around line #9): 7 def create 8 @cart_item = @cart.cart_items.build(product_id: session[:product_id]) if @cart_item.blank? 9 if @cart_item.save! 10 redirect_to current_cart 11 else 12 redirect_to products_path
if @cart_item.save!の「!」を外すと、elseに回って、products_path(商品一覧画面)にいきます。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/06 13:09
2020/09/06 22:51
2020/09/06 23:14
2020/09/06 23:21
2020/09/06 23:34
2020/09/06 23:46
2020/09/07 00:15
2020/09/07 00:22
2020/09/07 00:32
2020/09/07 00:51
2020/09/07 01:29