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_adminlayout_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 更改看看就可以看到改後的結果

results matching ""

    No results matching ""