前提・実現したいこと
現在、プログラミングを学習中の初学者です。
ポートフォリオ制作の一環でrailsでカート機能を備えたECサイトを作成しています。
ログイン状態でトップページに設定している、products#indexの「カートに入れる」ボタンを押すと、ユーザーidと紐づいたカートが生成され、cartテーブルとproductテーブルの中間テーブル的な役割を担うcart_itemテーブルに商品の個数と、それぞれのidを保存できるようにしたいです。
現在、「カートに入れる」ボタンを押すと、下記のエラーが吐かれてしまいます。
該当のフォームやルーティングに問題があるのでは無いかと思いますが、いろいろ調べてもどうしてよいか分かりません。
何日も解決できず困っています。アドバイスをいただけると幸いです。
申し訳ございませんがよろしくお願いいたします。
下記、エラーメッセージとソースコードです。
発生している問題・エラーメッセージ
ArgumentError in Products#index First argument in form cannot contain nil or be empty
該当のソースコード
Ruby
1#routes.rb 2root 'products#index' 3 4 resources :products, only: [:index, :new, :create, :edit, :update] do 5 resources :carts, only: [:create, :new] 6 collection do 7 post '/add_item' => 'carts#add_item' 8 post '/update_item' => 'carts#update_item' 9 delete '/delete_item' => 'carts#delete_item' 10 end 11 end 12 13 resources :users, only: [:show,:edit,:update] 14 15 resources :carts, only: [:show,:create,:new] 16
#app/views/products/index.html.haml #トップページと商品の購入ページを兼ねています。 %ul - @products.each do |product| %li.product .pro-main .pro-left .pro-image = image_tag product.image.url, height: "120" .pro-name = product.name .pro-center .pro-explain = product.explain .pro-right .pro-price = product.price %span 円 #以下フォーム =form_for([@product, @cart_item], url: add_item_products_path, method: :post) do |f| =f.hidden_field :product_id, value: @product.id /=f.hidden_field :cart_id, value: @cart.id .pro-qua = f.number_field :quantity, value: "0", style: "text-align:right", min: 0, class: "pro-quantity" .pro-cart = f.submit "カートに入れる", class: "cart-in", name: "add_cart"
#application_controller.rb #current_cartを定義しています helper_method :current_cart def current_cart @cart =Cart.find(session[:cart_id]) rescue ActiveRecord::RecordNotFound cart = Cart.create session[:cart_id] = cart.id cart end
#carts_controller.rb class CartsController < ApplicationController before_action :setup_cart_item!, only: [:add_item, :update_item, :delete_item] def show @cart_items = current_cart.cart_items end def add_item @cart = current_cart @product =Product.find(params[:product_id]) @cart_items = @cart.cart_items.build if @cart_item.blank? @cart_item = current_cart.cart_items.build(product_id: params[:product_id], cart_id: current_cart.id) end @cart_items.quantity += params[:quantity].to_i @cart_items.save redirect_to current_cart end def update_item @cart_item.update(quantity: params[:quantity].to_i) redirect_to current_cart end def delete_item @cart_item.destroy redirect_to current_cart end private def cart_params params.require(:cart).permit(cart_items: [:id, :product_id, :cart_id]) end def setup_cart_item! @cart_item = current_cart.cart_items.find_by(product_id: params[:product_id]) end end
#products_controller.rb class ProductsController < ApplicationController def index @products = Product.all end def new @product = Product.new end def create @product = Product.new(product_params) if @product.save redirect_to root_path else render new_product_path end end private def product_params params.require(:product).permit(:name, :explain, :image, :price) end end
#cart.rb class Cart < ApplicationRecord has_many :cart_items, dependent: :destroy has_many :products, through: :cart_items belongs_to :user end
#cart_item.rb class CartItem < ApplicationRecord belongs_to :product belongs_to :cart end
#product.rb class Product < ApplicationRecord mount_uploader :image, ImageUploader has_many :cart_items, dependent: :destroy has_many :cart, through: :cart_items end
#user.rb class User < ApplicationRecord has_one :cart, dependent: :destroy end
試したこと
下記の記述等を参考にしましたがうまくいきませんでした。
rails カート機能の実装(多対多)NoMethodError
RailsでEC系に良く出てくるカート機能を解説 / 実装してみた
Rails5でカート機能を作るためのロジックを作ってみた
ルーティングや、コントローラーの設定、フォームの使い方などに関する理解の浅さこそが最大の原因であると思いますが、どうにも進めなくなってしまい、お力添えをお願いしたいです。
補足情報(FW/ツールのバージョンなど)
Rails 5.0.7.2
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/07/05 03:27