学生向けプログラミング入門

学生向けにプログラミングを解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails

Ruby on Rails 6.0によるWebアプリケーション開発30 注文の詳細の取得

<<前  [TOP]  次>>


コントローラにcreate()アクションを実装します。
このメソッドでは次の処理を行います。

  1. フォームからの値を取得して新しいOrderモデルオブジェクトに格納する。
  2. カートに入っているLineItemをその注文に追加する。
  3. 注文のデータが正当かどうかを検証して保存する。注文データが不正である場合はエラーメッセージを表示してユーザに修正を求める。
  4. 注文が正常に保存されたらカートを削除し、カタログページを再表示して注文手続きが完了したところをメッセージで通知する。

まずは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



注文を受け付けるとインデックスページにリダイレクトし、「ご注文ありがとうございました。」というフラッシュメッセージが表示されます。

注文完了
注文完了


<<前  [TOP]  次>>