建立訂單

我們需要 「訂單」、「訂單資訊」、「訂單物品」這幾個資料結構

訂單:

$> mix phoenix.gen.model order orders user_id:references:users total:integer

訂單資訊:

$> mix phoenix.gen.model order_info order_infos order_id:references:orders billing_name:string billing_address:string shipping_name:string shipping_address:string

訂單物品

$> mix phoenix.gen.model order_item order_items order_id:references:orders product_name:string price:integer quantity:integer

設定關係:

#web/models/order.ex
  schema "orders" do
    field :total, :integer
    belongs_to :user, ShoppingSite.User

    has_many :items, ShoppingSite.OrderItem, on_delete: :delete_all
    has_one :info, ShoppingSite.OrderInfo, on_delete: :delete_all

    timestamps()
  end

  @required_fields ~w(user_id total)
  @optional_fields ~w()

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, @required_fields, @optional_fields)
    |> cast_assoc(:info, required: true)
    |> validate_required([:user_id, :total])
  end

增加結帳按鈕

#web/router.ex
  resources "/carts", CartController, only: [:index] do
    get "/check_out", CartController, :check_out, as: :check_out
  end
#web/templates/cart/index.html.eex
...
    <div class="checkout clearfix">
      <span class="pull-right">
        <%= link "Check out", 
            to: cart_check_out_path(@conn, :check_out, current_cart(@conn).id), 
            class: "btn btn-lg btn-danger" %>
      </span>
    </div>
  </div>
</div>  //end

為了要在 cart/index 使用 current_cart,在 cart_view import current_cart

#web/views/cart_view.ex
import ShoppingSite.CartController, only: [current_cart: 1]

check_out function

#web/controllers/cart_conotroller.ex

alias ShoppingSite.OrderInfo
alias ShoppingSite.Order

def check_out(conn, _params) do
  order_info_changeset = OrderInfo.changeset(%OrderInfo{})
  order_changeset = Order.changeset(%Order{info: order_info_changeset})
  render conn, "check_out.html", order_changeset: order_changeset
end

這樣表示我們在建立訂單時會先建立 OrderInfo 然後把它放到 Order的 changeset裡


填寫訂單資訊的頁面(check_out.html)

#web/templates/cart/check_out.html.eex
<div class="row">
  <div class="col-md-12">

    <table class="table table-bordered">
      <thead>
        <tr>
          <th width="80%">product information</th>
          <th>price</th>
        </tr>
      </thead>
      <tbody>
        <%= for product <- get_cart_items(@conn) do %>
          <tr>
            <td>
              <%= link to: product_path(@conn, :show, product.id) do%>
                <%= product.title %>
              <% end %>
            </td>
            <td>
              <%= product.price %>
            </td>
          </tr>
        <% end %>
      </tbody>
    </table>

    <div class="total clearfix">
      <span class="pull-right">
        total <%= cart_total_price(@conn) %>
      </span>
    </div>

    <h2>Order information</h2>
    <div class="order-form">
      <%= render "order_form.html", changeset: @order_changeset,
          action: order_path(@conn, :create) %>
    </div>
  </div>
</div>

cart_view 新增在 templates用到的方法

#web/views/cart_view.ex
def get_cart_items(conn) do
  products =
    Repo.preload(current_cart(conn), :products).products
end

還有order_form.html,用來填入訂單人資訊

<%= form_for @changeset, @action, fn f -> %>
  <%= if @changeset.action do %>
    <div class="alert alert-danger">
      <p>Oops! something went wrong!</p>
    </div>
  <%= end %>

  <%= inputs_for f, :info, fn fp -> %>
    <div class="form-group">
      <%= label fp, :billing_name, class: "control-label" %>
      <%= text_input fp, :billing_name, class: "form-control" %>
      <%= error_tag fp, :billing_name %>
    </div>

    <div class="form-group">
      <%= label fp, :billing_address, class: "control-label" %>
      <%= text_input fp, :billing_address, class: "form-control" %>
      <%= error_tag fp, :billing_address %>
    </div>

    <div class="form-group">
      <%= label fp, :shipping_name, class: "control-label" %>
      <%= text_input fp, :shipping_name, class: "form-control" %>
      <%= error_tag fp, :shipping_name %>
    </div>

    <div class="form-group">
      <%= label fp, :shipping_address, class: "control-label" %>
      <%= text_input fp, :shipping_address, class: "form-control" %>
      <%= error_tag fp, :shipping_address %>
    </div>
  <% end %>

  <div class="form-group">
    <%= submit "Check out", class: "btn btn-lg btn-danger pull-right" %>
  </div>

<% end %>


我們也需要 Ordercreate 才能建立訂單

results matching ""

    No results matching ""