15 - 建立訂單相關設定
我們建立玩訂單會想要看自己訂了什麼,可是不希望網址是 user/orders/1 這樣,這樣很容易被其他人存取,因此希望把訂單網址做編碼,可以用 uuid
這個 library做到
在 mix.exs 加入 uuid
#web/mix.exs
defp deps do
...[
{:uuid, "~> 1.1"}]
end
#web/models/order.ex
@required_fields ~w(user_id total)
@optional_fields ~w(token)
def changeset(struct, params \\ %{}) do
struct
|> cast(params, @required_fields, @optional_fields)
|> put_token()
|> cast_assoc(:info, required: true)
|> validate_required([:user_id, :total])
end
def put_token(changeset) do
case changeset.valid? do
true ->
put_change(changeset, :token, UUID.uuid4())
false ->
changeset
end
end
加入 show
方法,並將輸入的參數改成 token
#web/controllers/order_controller.ex
def show(conn, %{"token" => token}) do
order = Repo.get_by(Order, token: token)
order_info = Repo.preload(order, :info).info
order_items = Repo.preload(order, :items).items
render conn, "show.html", order: order, order_info: order_info, order_items: order_items
end
router 這邊也要改成看 token
#web/router.ex
scope "/", ShoppingSite do
...
resources "/orders", OrderController, param: "token"
end
顯示訂單頁面
#web/controllers/order_controller.ex
<div class="row">
<div class="col-md-12">
<h2>Order information</h2>
<table class="table table-bordered">
<thead>
<tr>
<th width="80%">Product Information</th>
<th>Price</th>
<th>quantity</th>
</tr>
</thead>
<tbody>
<%= for each_item <- @order_items do %>
<tr>
<td><%= each_item.product_name %></td>
<td><%= each_item.price %></td>
<td><%= each_item.quantity %></td>
</tr>
<% end %>
</tbody>
</table>
<div class="total clearfix">
<span class="pull-right">
total <%= @order.total %>
</span>
</div>
<hr>
<h2> Shipping information </h2>
<table class="table table-striped table-bordered">
<tbody>
<tr>
<td>sender</td>
</tr>
<tr>
<td><%= @order_info.billing_name %> - <%= @order_info.billing_address %></td>
</tr>
<tr>
<td>receiver</td>
</tr>
<tr>
<td>
<%= @order_info.shipping_name %> - <%= @order_info.shipping_address %>
</td>
</tr>
</tbody>
</table>
</div>
</div>
不要忘記 view
喔!
#web/controllers/order_view.ex
defmodule ShoppingSite.OrderView do
use ShoppingSite.Web, :view
end
現在可以先用以下方法取得訂單編碼
$> ShoppingSite.Repo.get(ShoppingSite.Order, id)
然後用 localhost:4000/orders/XXXXXXX
看看是否正確顯示