Railsでネットショップを開発しております。
下記2点の機能を実装したいのですが、どのようなロジックにすれば実装できるか教えていただきたく、質問致しました。
よろしくお願い致します。
- 注文をするボタンを押した後に、そのユーザーのカートの中身を空にしたい
- これまでに自分が注文した履歴を表示するページを作成したい
商品をカートに入れてから注文を確定するまでの流れは現状以下のようになっております。
・商品一覧ページです
・商品をカートに入れる個数を選択するページです
・カートの中身を表示するページです(hoge2は商品名、222は値段、4は個数です)
・注文を出すためのページです
・注文をするボタンを押すとカート表示ページに飛びます
注文履歴ページに関しては下記の画像のような表示をイメージしております
各モデルとコントローラーは以下になります
ruby
1#カート 2class Cart < ApplicationRecord 3 belongs_to :user 4 has_many :cart_items 5end 6 7#カートに入れた商品 8class CartItem < ApplicationRecord 9 belongs_to :product 10 belongs_to :cart 11end 12 13#注文 14class Order < ApplicationRecord 15 has_many :cart_item, dependent: :destroy 16end 17 18#商品 19class Product < ApplicationRecord 20 has_many :carts, through: :cart_items 21 mount_uploader :picture, PictureUploader 22end
ruby
1class CartItemsController < ApplicationController 2 before_action :setup_item, only: [:destroy] 3 4 def destroy 5 @setup_item.destroy 6 redirect_to current_cart 7 8 end 9 10 private 11 12 def setup_item 13 @setup_item = CartItem.find(params[:id]) 14 end 15end
ruby
1class CartsController < ApplicationController 2 before_action :setup_cart_item, only: [:add_item, :delete_item, :show] 3 4 def show 5 @cart_items = CartItem.where(cart_id:current_cart.id) 6 @total_price = 0 7 if @cart_items 8 @cart_items.each do |cart_item| 9 @total_price += cart_item.product.price * cart_item.quantity 10 end 11 end 12 end 13 14 def add_item 15 if CartItem.find_by(product_id: params[:product_id], cart_id: current_cart.id).blank? 16 @cart_item = current_cart.cart_items.create(product_id: params[:product_id]) 17 end 18 19 @cart_item.quantity += params[:product][:quantity].to_i 20 @cart_item.save! 21 redirect_to current_cart 22 end 23 24 def destroy 25 @cart_item.destroy 26 redirect_to current_cart 27 28 end 29 30 def delete_item 31 @cart_item.destroy 32 redirect_to current_cart 33 end 34 35 private 36 37 def setup_cart_item 38 @cart_item = CartItem.find_by(cart_id: current_cart.id,product_id: params[:product_id]) 39 end 40end
ruby
1class OrdersController < ApplicationController 2 def index 3 @orders = Order.all 4 end 5 6 def show 7 end 8 9 def new 10 @order = Order.new 11 end 12 13 def create 14 @order = Order.new(order_params) 15 @cart_items = CartItem.where(cart_id:current_cart.id) 16 redirect_to current_cart 17 end 18 19 def destroy 20 @order.destroy 21 end 22 23 private 24 25 def set_order 26 @order = Order.find(params[:id]) 27 end 28 29 def order_params 30 params.require(:order).permit(:name, :address, :email) 31 end 32end 33
ruby
1class ProductsController < ApplicationController 2 def index 3 @products = Product.all 4 end 5 6 def show 7 @product = Product.find(params[:id]) 8 end 9 10 def new 11 @product = Product.new 12 end 13 14 def create 15 @product = Product.new(product_params) 16 if @product.save # => Validation 17 # Sucess 18 flash[:success] = "商品を登録しました" 19 redirect_to root_url 20 else 21 render 'new' 22 end 23 end 24 25 def ensure_correct_user 26 if current_user.admin? 27 else 28 flash[:notice] = "アクセス権限がありません" 29 redirect_to root_url 30 end 31 end 32 33 private 34 35 def product_params 36 params.require(:product).permit(:name, :price) 37 params.require(:product).permit(:title, :memo, :author, :picture) 38 end 39end 40
加筆
ユーザのカートを空にするmethodを仮に user.cart.clear としたときに、それをどのcontrllerのどのアクションのどの位置に入れるか
カートの中身を空にするタイミングは、orderが作成(注文が確定)されたタイミングで行いたいと考えております。
ruby
1class OrdersController < ApplicationController 2 3def create 4 @order = Order.new(order_params) 5 @cart_items = CartItem.where(cart_id:current_cart.id) 6 redirect_to current_cart 7 8 user.cart.clear #カートの中身を空にする 9 10 end 11 12end 13
履歴一覧を出すにあたって、何がわからないのでしょうか
現状ではカートの中に入っている商品はcart_itemで管理しています。cart_itemにはカートのid(cart_id)、商品のid(product_id)、商品の個数(quantity)の情報を保存しています。
orderでは1つのidに対して1つの注文を管理したいのですが、1回の注文で複数の商品を購入する場合もあるため、
order1つに対して複数のproduct_idを紐付ける必要がありそうですが、prpduct_idの個数が可変なため、それはできないと思い、他に方法はないか、というのが現時点での疑問になります。
例えばAさんというユーザー(user_id=2とする)はcart_id=3のカートと紐付いていて、現在カートに3つの商品が入っていたとすると、cart_item(CartItem.where(cart_id:3))は以下のようになります。
この状態で注文をした場合、orderを以下のようなイメージで作成できればと思っております(cart_idがuser_idになっても可)
回答1件
あなたの回答
tips
プレビュー