7 - 管理使用者權限
建立管理使用者介面,可以列出使用者列表,以及升級使用者權限
#ruby web/router.ex
scope "/admin", ShoppingSite.Admin, as: :admin do
pipe_through :browser
resources "/products", ProductController
resources "/users", UserController
end
加入一個 admin layout 到 product/index、user/index
但是找不到好的寫法,所以先寫成在 index裡面 render另一個 template
#web/templates/admin/product/index.html.eex
<%= render ShoppingSite.LayoutView, "admin.html", conn: @conn %>
<h1>Products</h1>
#web/tmeplates/layout/admin.html
<%= link "product" , to: admin_product_path(@conn, :index), class: "btn btn-primary" %>
列出所有使用者,加入 UserController
#web/controllers/admin/user_controller.ex
defmodule ShoppingSite.Admin.UserController do
use ShoppingSite.Web, :controller
alias ShoppingSite.User
import ShoppingSite.UserController, only: [authenticate: 2]
plug :authenticate
def index(conn, _params) do
users = Repo.all(User)
render conn, "index.html", users: users
end
end
必須要先登入才能進來所以我們 import :authenticate
這個 plug
列出所有使用者,並且根據權限列出對應的按鈕
#web/templates/admin/user/index.html.eex
<%= render ShoppingSite.LayoutView, "admin.html" , conn: @conn %>
<h2>User list</h2>
<table class="table table-bordered">
<thead>
<tr>
<th>#</th>
<th>Email</th>
<th>authoroty</th>
<th>operation</th>
</tr>
</thead>
<tbody>
<%= for user <- @users do %>
<tr>
<td><%= user.id %></td>
<td><%= user.email %></td>
<td><%= show_authority(user) %></td>
<td>
<%= if is_admin(user) do %>
<%= link "To normal user", to: "#", class: "btn btn-info" %>
<% else %>
<%= link "To Admin", to: "#", class: "btn btn-primary" %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
別忘記 admin/user_view.ex
#web/views/admin/user_view.ex
defmodule ShoppingSite.Admin.UserView do
use ShoppingSite.Web, :view
def show_authority(user) do
if user.admin do
"Admin"
else
"normal user"
end
end
def is_admin(user) do
user.admin
end
end
在 navbar上面建立「管理」連結,裡面可以管理商品、帳號
#web/templates/layout/navbar.html.eex
<ul class="dropdown-menu">
<%= if is_admin(@conn.assigns.current_user) do %>
<li><%= link "Product Management", to: admin_product_path(@conn, :index) %></li>
<% end %>
...
加入 is_admin
到 layout_view.ex
#web/views/layout_view.ex
def is_admin(user) do
user.admin
end
升級使用者權限這邊呢,想法如下:
按了升級按鈕
-> 送 user資料給 controller
-> controller更新 user資料
-> update database
定義一個新的 route
#web/router.ex
scope "/admin", ShoppingSite.Admin, as: :admin do
...
get "/change_authority/:id", UserController, :change_authority
end
我們就可以利用那個 id去取出使用者
#web/controllers/admin/user_controller.ex
def change_authority(conn, %{"id" => id}) do
extracted_user = Repo.get!(ShoppingSite.User, id)
Ecto.Changeset.change(extracted_user, %{admin: !extracted_user.admin})
|> Repo.update
users = Repo.all(ShoppingSite.User)
conn
|> render("index.html", users: users)
end
要記得把這個功能在網頁上開出來,也就是在 admin.html
把他叫出來
+<%= link "users" , to: admin_user_path(@conn, :index), class: "btn btn-primary" %>
把上面做的列出所有使用者的那幾個按鈕導到change_authority
#web/templates/admin/user/index.html.eex
<td>
<%= if is_admin(user) do %>
<%= link "To normal user", to: admin_user_path(@conn, :change_authority, user.id), class: "btn btn-info" %>
<% else %>
<%= link "To Admin", to: admin_user_path(@conn, :change_authority, user.id), class: "btn btn-primary" %>
<% end %>
</td>
進去 admin/users 更改看看就可以看到改後的結果