🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1824閲覧

注文履歴を表示するロジックを作りたい Railsでネットショップ

ryota1017stars

総合スコア21

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

1クリップ

投稿2019/10/13 02:48

編集2019/10/13 07:57

Railsでネットショップを開発しております。

下記2点の機能を実装したいのですが、どのようなロジックにすれば実装できるか教えていただきたく、質問致しました。
よろしくお願い致します。

  1. 注文をするボタンを押した後に、そのユーザーのカートの中身を空にしたい
  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になっても可)

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

winterboum

2019/10/13 05:21

読み解くのが厄介ですので ユーザのカートを空にするmethodを仮に user.cart.clear としたときに、それをどのcontrllerのどのアクションのどの位置に入れるか、を示していただけますか 履歴一覧を出すにあたって、何がわからないのでしょうか
siruku6

2019/10/13 06:51 編集

そもそもorderレコードを作成する処理がないように見えるので、まずはOrderをcreateする処理をどこかに作らないといけなさそうですね。 そのときのテーブル構造を考えるところからになると思いますが、、、  ・order has_many 注文したitem にするのか、それとも  ・order1件には1件のitem情報を保存 にするのか、、、、といったことを考えてからプログラミングした方がよさそうです。 --- それとは別の話ですが、質問が複数あると、全部解決するまで解決済みにできないと思いますので、今からでも質問を2つに分けた方がよいかもしれませんね。
ryota1017stars

2019/10/13 07:59

winterboum様 いつもありがとうございます。質問の追記をいたしました。もし説明に不明点や追記が必要な場合は再度お申し付けください。よろしくお願いいたします。
ryota1017stars

2019/10/13 08:03

siruku様 アドバイスありがとうございます。 Orderをcreateする処理はOrdersController内のcretaeメソッドで実装し、show.html.erb内でnew_order_pathを呼び出しております。 質問を分ける件、大変参考になりました。ありがとうございます。今から分けると混乱しそうなので、次からは分けるようにしたいと思います。
guest

回答1

0

ベストアンサー

すると、質問の前半は user.cart.clear を実装するだけですね。
class Cart に cart_items を消す def clear を実装するのはできますよね?
method名がclearで良いかどうかは考えて下さい。

投稿2019/10/13 09:30

winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ryota1017stars

2019/10/13 09:51

ご回答ありがとうございます。もう1点の質問ですが、分割して別に投稿いたしました。 https://teratail.com/questions/217027?modal=q-comp よければこちらの方でアドバイスいただけたらと思います。お手数おかけしますが、よろしくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問