前提・実現したいこと
現在、プログラミングを学習中の初学者です。
ポートフォリオ制作の一環でrailsでカート機能を備えたECサイトを作成しています。
ログイン状態でトップページに設定している、products#indexの「カートに入れる」ボタンを押すと、ユーザーidと紐づいたカートが生成され、cartテーブルとproductテーブルの中間テーブル的な役割を担うcart_itemテーブルに商品の個数と、それぞれのidを保存できるようにしたいです。
現在、「カートに入れる」ボタンを押すと、下記のエラーが吐かれてしまいます。
該当のフォームやルーティングに問題があるのでは無いかと思いますが、いろいろ調べてもどうしてよいか分かりません。
何日も解決できず困っています。アドバイスをいただけると幸いです。
申し訳ございませんがよろしくお願いいたします。
下記、エラーメッセージとソースコードです。
発生している問題・エラーメッセージ
該当のソースコード
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 member 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
Haml
1#app/views/products/index.html.haml 2#トップページと商品の購入ページを兼ねています。 3 4 %ul 5 - @products.each do |product| 6 =form_for([@product, @cart_item], url: add_item_product_path(product), method: :post) do |f| 7 %li.product 8 .pro-main 9 .pro-left 10 .pro-image 11 = image_tag product.image.url, height: "120" 12 .pro-name 13 = product.name 14 .pro-center 15 .pro-explain 16 = product.explain 17 .pro-right 18 .pro-price 19 = product.price 20 %span 21 円 22 =f.hidden_field :product_id, value: product.id 23 .pro-qua 24 = f.number_field :quantity, value: "0", style: "text-align:right", min: 0, class: "pro-quantity" 25 .pro-cart 26 = f.submit "カートに入れる", class: "cart-in", name: "add_cart"
Ruby
1#application_controller.rb 2#current_cartを定義しています 3 helper_method :current_cart 4 5 def current_cart 6 @cart = Cart.find_by(id: session[:cart_id]) || Cart.create 7 session[:cart_id] = @cart.id 8 @cart 9 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[:id]) @cart_items = @cart.cart_items.build if @cart_item.blank? @cart_item = current_cart.cart_items.build(product_id: params[: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
Ruby
1#products_controller.rb 2class ProductsController < ApplicationController 3 4 def index 5 @products = Product.all 6 @cart_item = CartItem.new 7 end 8 9 def new 10 @product = Product.new 11 end 12 13 def create 14 @product = Product.new(product_params) 15 if @product.save 16 redirect_to root_path 17 else 18 render @product.current_cart 19 end 20 end 21 22 private 23 def product_params 24 params.require(:product).permit(:name, :explain, :image, :price) 25 end 26 27end
Ruby
1#cart.rb 2class Cart < ApplicationRecord 3 has_many :cart_items, dependent: :destroy 4 has_many :products, through: :cart_items 5 belongs_to :user 6end
Ruby
1#cart_item.rb 2class CartItem < ApplicationRecord 3 belongs_to :product 4 belongs_to :cart 5end
Ruby
1#product.rb 2class Product < ApplicationRecord 3 mount_uploader :image, ImageUploader 4 has_many :cart_items, dependent: :destroy 5 has_many :cart, through: :cart_items 6end
Ruby
1#user.rb 2class User < ApplicationRecord 3 has_one :cart, dependent: :destroy 4end
Prefix Verb URI Pattern Controller#Action new_user_session GET /users/sign_in(.:format) users/sessions#new user_session POST /users/sign_in(.:format) users/sessions#create destroy_user_session DELETE /users/sign_out(.:format) users/sessions#destroy new_user_password GET /users/password/new(.:format) devise/passwords#new edit_user_password GET /users/password/edit(.:format) devise/passwords#edit user_password PATCH /users/password(.:format) devise/passwords#update PUT /users/password(.:format) devise/passwords#update POST /users/password(.:format) devise/passwords#create cancel_user_registration GET /users/cancel(.:format) users/registrations#cancel new_user_registration GET /users/sign_up(.:format) users/registrations#new edit_user_registration GET /users/edit(.:format) users/registrations#edit user_registration PATCH /users(.:format) users/registrations#update PUT /users(.:format) users/registrations#update DELETE /users(.:format) users/registrations#destroy POST /users(.:format) users/registrations#create sign_in GET /sign_in(.:format) users/sessions#new sign_out GET /sign_out(.:format) users/sessions#destroy root GET / products#index product_carts POST /products/:product_id/carts(.:format) carts#create new_product_cart GET /products/:product_id/carts/new(.:format) carts#new product_cart GET /products/:product_id/carts/:id(.:format) carts#show add_item_product POST /products/:id/add_item(.:format) carts#add_item update_item_product POST /products/:id/update_item(.:format) carts#update_item delete_item_product DELETE /products/:id/delete_item(.:format) carts#delete_item products GET /products(.:format) products#index POST /products(.:format) products#create new_product GET /products/new(.:format) products#new edit_product GET /products/:id/edit(.:format) products#edit product PATCH /products/:id(.:format) products#update PUT /products/:id(.:format) products#update edit_user GET /users/:id/edit(.:format) users#edit user GET /users/:id(.:format) users#show PATCH /users/:id(.:format) users#update PUT /users/:id(.:format) users#update
試したこと
下記の記述等を参考にしましたがうまくいきませんでした。
rails カート機能の実装(多対多)NoMethodError
RailsでEC系に良く出てくるカート機能を解説 / 実装してみた
Rails5でカート機能を作るためのロジックを作ってみた
ルーティングや、コントローラーの設定、フォームの使い方などに関する理解の浅さこそが最大の原因であると思いますが、どうにも進めなくなってしまい、お力添えをお願いしたいです。
補足情報(FW/ツールのバージョンなど)
Rails 5.0.7.2
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/07/05 08:24
2020/07/05 09:29
退会済みユーザー
2020/07/05 12:34
2020/07/05 13:26
退会済みユーザー
2020/07/05 14:51
2020/07/05 22:52
2020/07/06 00:45