Ruby on Railsでショッピングカート機能を実装しています。
商品一覧画面から、商品の個数を選択してcartテーブルに保存したい状況です。
※cartテーブルはsessionで仮に商品を保存するためのテーブルとなってます。
そして商品一覧indexのコントローラーで、cart.newを記述して、cartのコントローラーで
createメソッドに飛ばしています。
環境:
rails 5.2.3
gem devise機能を使用
ruby
1index前のコントローラーになります。 2class BoxlunchesController < ApplicationController 3 def index 4 @boxlunches = Boxlunch.all 5 @cart = Cart.new 6 end 7 8 def show 9 end 10end 11 12
課題:
商品一覧画面から、商品の個数(boxlunch_quantity)を選択し、formで値を送信するが、boxlunch_quantityのみ保存されない
※boxlunch_idはcart_itemテーブルに保存されます。
Ruby
1 index.html.haml 2 3 = render 'layouts/header' 4= render "./template/menu_selections" 5.menu-container 6 %h2 Boxlunch Menu 7 .menu-contents 8 - @boxlunches.each do |boxlunch| 9 #cart_index_pathでcartのcreateに飛びます 10 = form_for @cart, url: cart_index_path(boxlunch_id: boxlunch.id), method: :post do |f| 11 .menu-package 12 .menu-image 13 = link_to "boxlunch/#{boxlunch.id}" do 14 = image_tag boxlunch.image, width:"200px", height:"150px" 15 %h4 16 = link_to do 17 = boxlunch.name 18 .count-price-container 19 .count-price 20 .price 21 %p ¥#{boxlunch.price}(税込) 22 .count 23 %label 24 =f.select :boxlunch_quantity, options_for_select(1..10), include_blank: '0' 25 =f.submit "カートの中に入れる" 26= render 'layouts/footer'
エラー内容
ブラウザーではエラーは表示されていないので
ターミナルでの記載になります。
ruby
1ターミナル 2Started POST "/cart?boxlunch_id=1" for ::1 at 2020-01-13 23:49:36 +0900 3Processing by CartController#create as HTML 4 Parameters: {"utf8"=>"✓", "authenticity_token"=>"O5g+me6pcK+uueZYWtdRBmkFdj+TzXqkyZRyw+q5KvkcqQ3wGLzM05qi79LfoOL9vd7aI54B78hSBNdXYOML2A==", "cart"=>{"boxlunch_quantity"=>"1"}, "commit"=>"カートの中に入れる", "boxlunch_id"=>"1"} 5 Order Load (2.0ms) SELECT "orders".* FROM "orders" WHERE "orders"."id" IS NULL LIMIT $1 [["LIMIT", 1]] 6 ↳ app/controllers/application_controller.rb:16 7 (0.8ms) BEGIN 8 ↳ app/controllers/application_controller.rb:17 9 (1.1ms) ROLLBACK 10 ↳ app/controllers/application_controller.rb:17 11 Boxlunch Load (0.7ms) SELECT "boxlunches".* FROM "boxlunches" WHERE "boxlunches"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 12 ↳ app/controllers/cart_controller.rb:4 13 Order Load (1.6ms) SELECT "orders".* FROM "orders" WHERE "orders"."id" IS NULL LIMIT $1 [["LIMIT", 1]] 14 ↳ app/controllers/application_controller.rb:16 15 (1.8ms) BEGIN 16 ↳ app/controllers/application_controller.rb:17 17 (0.4ms) ROLLBACK 18 ↳ app/controllers/application_controller.rb:17 19 (1.0ms) BEGIN 20 ↳ app/controllers/cart_controller.rb:6 21 Cart Create (0.5ms) INSERT INTO "carts" ("boxlunch_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["boxlunch_id", 1], ["created_at", "2020-01-13 14:49:36.819147"], ["updated_at", "2020-01-13 14:49:36.819147"]] 22 ↳ app/controllers/cart_controller.rb:6 23 (1.9ms) COMMIT 24 ↳ app/controllers/cart_controller.rb:6 25 User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]] 26 ↳ app/controllers/cart_controller.rb:7 27Redirected to http://localhost:3000/cart/1 28Completed 302 Found in 46ms (ActiveRecord: 12.1ms) 29 30 31Started GET "/cart/1" for ::1 at 2020-01-13 23:49:36 +0900 32Processing by CartController#show as HTML 33 Parameters: {"id"=>"1"} 34 Rendering cart/show.html.haml within layouts/application 35 Rendered cart/show.html.haml within layouts/application (1.9ms) 36Completed 200 OK in 63ms (Views: 60.4ms | ActiveRecord: 0.0ms)
アプリケーションコントローラーのコード
※current_cartを定義しています。
ruby
1 class ApplicationController < ActionController::Base 2 protect_from_forgery with: :exception 3 before_action :authenticate_user! 4 5 6 def after_sign_in_path_for(resource) 7 root_path # ログイン後に遷移するpathを設定 8 end 9 10 def after_sign_out_path_for(resource) 11 root_path # ログアウト後に遷移するpathを設定 12 end 13 14 private 15 def current_cart 16 @current_cart = Order.find_by(id: session[:order_id]) 17 @current_cart = Order.create unless @current_cart 18 session[:order_id] = @current_cart.id 19 @current_cart 20 end 21end 22
カートのモデルコード
ruby
1class Cart < ApplicationRecord 2 belongs_to :order 3 has_many :boxlunches 4 5 6 def add_boxlunch(boxlunch_id) 7 cart.find_or_initialize_by(boxlunch_id: boxlunch_id) 8 end 9 10 def add_single_menu(single_menu_id) 11 cart.find_or_initialize_by(single_menu_id: single_menu_id) 12 end 13end
カートのコントローラーのコード
ruby
1class CartController < ApplicationController 2 def create 3 cart = current_cart 4 boxlunch = Boxlunch.find(params[:boxlunch_id]) 5 @cart = current_cart.add_boxlunch(boxlunch.id) 6 if @cart.save 7 redirect_to cart_path(current_user) 8 else 9 render :new 10 end 11 end 12 13 private 14 def cart_params 15 params.require(:cart).permit(:boxlunch_quantity); 16 end 17 end
以上のような状況です。
お忙しい中ですが、教えていただけますと助かります。
宜しくお願いいたします。
プログラム類は 逆シングルコーテーション3つの間にいれてインデントが判るようにしてください。
インデント命のhamlが、、、、
RUBYのcodeも読みにくい。
読みにくいと読んでもらえないので、回答がつきにくいです
teisei
winterboumさん
ご回答ありがとうございます。
①order_idが代入されるのは、17行目のsession[:order_id] = @current_cart.id です。
loginの時に定義しておりません。
②orderテーブルは、boxlunchとcart_itemの中間テーブルに位置するものです。
そして、logを撮った時とコードは同じです。
すみません!逆シングルコーテーション3つの間にいれてインデントが判るようにするということがわからないです。
""を``に変更するということですか。 3つの間とはどうゆうことですか?
以上、ご確認よろしくお願いします。
モデルの関係性をER図で書きましたので、一度ご確認していただけたら
嬉しいです。
cart_itemの方は、index.htmlに遷移する前のコントローラーで,
cart_item.newをしています。
order.newも必要でしょうか?
index.htmlの前のコントローラもコードを追記しておきます。
すみませんが、ご確認お願いいたします。
Boxlunch と Order をつなぐものが CartItemというのはいただけません。
CarItemという名前からは CartとItemをつなぐものと誤解されます、
これは直したほうがよい
OrderとAddressの関連はない方が自然です。
Addressが沢山Orderをもつとか、Orderがaddressに属するというのは不自然。
Orderの送り先という考えかと思いますが、OrderしたのはUser,そのaddressへ送ればよいのです
回答1件
あなたの回答
tips
プレビュー