<<前 [TOP] 次>>
コントローラにcreate()アクションを実装します。
このメソッドでは次の処理を行います。
- フォームからの値を取得して新しいOrderモデルオブジェクトに格納する。
- カートに入っているLineItemをその注文に追加する。
- 注文のデータが正当かどうかを検証して保存する。注文データが不正である場合はエラーメッセージを表示してユーザに修正を求める。
- 注文が正常に保存されたらカートを削除し、カタログページを再表示して注文手続きが完了したところをメッセージで通知する。
まずはLineItemからOrderへのリレーションシップの定義です。
「C:\Rails6\work\shop\app\models」フォルダにある「line_item.rb」ファイルを以下のように編集します。
【C:\Rails6\work\shop\app\models\line_item.rb】
class LineItem < ApplicationRecord belongs_to :order, optional: true belongs_to :good belongs_to :cart, optional: true def total_price good.price * quantity end end
次はOrderからLineItemへのリレーションシップです。
注文を削除するときにはその注文に関連付けられたLineItemもすべて削除するように指定します。
「order.rb」ファイルを以下のように編集します。
【C:\Rails6\work\shop\app\models\order.rb】
class Order < ApplicationRecord enum pay_type: { "現金" => 0, "クレジットカード" => 1, "着払い" => 2 } has_many :line_items, dependent: :destroy validates :name, :address, :email, presence: true validates :pay_type, inclusion: pay_types.keys end
「orders_controller.rb」ファイルの「create()」メソッドの最終的なコードは以下のようになります。
【C:\Rails6\work\shop\app\controllers\orders_controller.rb】
class OrdersController < ApplicationController include CurrentCart before_action :set_cart, only: [:new, :create] before_action :ensure_cart_isnt_empty, only: :new before_action :set_order, only: [:show, :edit, :update, :destroy] # GET /orders # GET /orders.json def index @orders = Order.all end # GET /orders/1 # GET /orders/1.json def show end # GET /orders/new def new @order = Order.new end # GET /orders/1/edit def edit end # POST /orders # POST /orders.json def create @order = Order.new(order_params) @order.add_line_items_from_cart(@cart) respond_to do |format| if @order.save Cart.destroy(session[:cart_id]) session[:cart_id] = nil format.html { redirect_to market_index_url, notice: 'ご注文ありがとうございました。' } format.json { render :show, status: :created, location: @order } else format.html { render :new } format.json { render json: @order.errors, status: :unprocessable_entity } end end end # PATCH/PUT /orders/1 # PATCH/PUT /orders/1.json def update respond_to do |format| if @order.update(order_params) format.html { redirect_to @order, notice: 'Order was successfully updated.' } format.json { render :show, status: :ok, location: @order } else format.html { render :edit } format.json { render json: @order.errors, status: :unprocessable_entity } end end end # DELETE /orders/1 # DELETE /orders/1.json def destroy @order.destroy respond_to do |format| format.html { redirect_to orders_url, notice: 'Order was successfully destroyed.' } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_order @order = Order.find(params[:id]) end # Only allow a list of trusted parameters through. def order_params params.require(:order).permit(:name, :address, :email, :pay_type) end def ensure_cart_isnt_empty if @cart.line_items.empty? redirect_to market_index_url, notice: 'カートは空です。' end end end
createメソッドで「add_line_items_from_cart()」メソッドを持っていると仮定したので、そのメソッドをOrderモデルに実装します。
【C:\Rails6\work\shop\app\models\order.rb】
class Order < ApplicationRecord enum pay_type: { "現金" => 0, "クレジットカード" => 1, "着払い" => 2 } has_many :line_items, dependent: :destroy validates :name, :address, :email, presence: true validates :pay_type, inclusion: pay_types.keys def add_line_items_from_cart(cart) cart.line_items.each do |item| item.cart_id = nil line_items << item end end end
注文を受け付けるとインデックスページにリダイレクトし、「ご注文ありがとうございました。」というフラッシュメッセージが表示されます。
↓↓クリックして頂けると励みになります。