有了管理員權限驗證後,接著我們在後台實作會員管理的功能。新手可能會有一個疑惑,要怎麼決定完成一個功能的先後順序比較恰當?雖然說理想上當所有元素都備齊後,功能就會如預期般運作,在這種情況下,順序好像無關緊要。但好的順序可以讓開發者對於功能與需求有更深的了解,也容易提早發現錯誤或需求的不明確之處。我個人通常是使用「行為導向開發」,從使用者操作這個功能時會接觸到的行為開發優先順序,也可以稱之為「錯誤導向開發」。
以會員管理為例:首先造訪我們預想中完成後的網址 http://localhost:4000/admin/users ,理所當然的會得到錯誤,訊息為 no route found for GET /admin/users
,所以我們先新增路由。
scope "/admin", ShopWeb.Admin, as: :admin do
pipe_through :browser
resources "/products", ProductController
resources "/users", UserController
end
在admin
的scope block裡面新增user resources,確認一下路徑是否正確 mix phx.routes
。再一次訪問剛剛的網址,現在我們得到 function ShopWeb.Admin.UserController.init/1 is undefined
,所以我們接下來寫controller。
因為user model之前已經產生,所以我們這次不使用工具,而是手動新增檔案的方式進行。
# lib/shop_web/controllers/admin/user_controller.ex
defmodule ShopWeb.Admin.UserController do
use ShopWeb, :controller
alias Shop.{User, Repo}
import ShopWeb.UserController, only: [authenticate: 2]
plug :authenticate
def index(conn, _params) do
users = Repo.all(User)
render(conn, "index.html", users: users)
end
end
這時的錯誤訊息變為 module ShopWeb.Admin.UserView is not available
,意思是我們缺少view
# lib/shop_web/views/admin/user_view.ex
defmodule ShopWeb.Admin.UserView do
use ShopWeb, :view
end
訊息為Could not render "index.html" for ShopWeb.Admin.UserView
,缺少template
# lib/shop_web/templates/admin/user/index.html.eex
<h2>Listing Users</h2>
<table class="table">
<thead>
<tr>
<th>Username</th>
<th>Email</th>
<th>Admin</th>
<th></th>
</tr>
</thead>
<tbody>
<%= for user <- @users do %>
<tr>
<td><%= user.username %></td>
<td><%= user.email %></td>
<td><%= user.admin %></td>
<td class="text-right">
<span><%= link "Edit", to: admin_user_path(@conn, :edit, user), class: "btn btn-default btn-xs" %></span>
<span><%= link "Delete", to: admin_user_path(@conn, :delete, user), method: :delete, data: [confirm: "Are you sure?"], class: "btn btn-danger btn-xs" %></span>
</td>e
</tr>
<% end %>
</tbody>
</table>
現在訪問就沒有錯誤,會看見一個基本的會員列表,但是修改刪除查詢都沒有功能,因為我們剛剛controller只有寫index,但是道理基本雷同。這邊就不一一贅述,有需要可以參考專案的github。
現在我們後台有兩個頁面,為了方便起見,我們在上方新增頁籤:
# lib/shop_web/templates/layout/app.html.eex
...
<%= if @current_user do %>
<%= if @current_user.admin do %>
<li><%= link "Users" , to: admin_user_path(@conn, :index) %></li>
<li><%= link "Products" , to: admin_product_path(@conn, :index) %></li>
<% end %>
<li><%= @current_user.username %></li>
<li><%= link "Log out", to: session_path(@conn, :delete, @current_user), method: "delete" %></li>
<% else %>
...
在有登入的情況下,如果是管理員,則出現兩個管理頁面的首頁,完成後就可以自由切換囉!