Railsで管理画面 - ユーザー 編

前回の続き

michimo-10.hatenablog.com

・コントローラー


adminの時はbase_controllerを使っているので、今まで使っていたApplicationControllerで作ったboards_controllerやuser_controller。。。などは引き継がれない(引っ張ってくることが出来ない)

つまり、もう一度boards_controllerやuser_controllerを定義し直さなければならない

とは言え一度作成しているので使いたい中身はほぼ同じ。ただ挙動を変える必要があるくらいだ。

また、今課題には今までに無かったuserの一覧画面の作成があるのでuserの情報を取って来なければならない。その辺りはコントローラーで明記し、ビューで表示させる。

まずは管理者用のboardsコントローラーの作成




続いてboardと同じようにusers_controllerを作成

rails g controller admin::Users # この時オプションでビューも作っていいがビューは後から個別で作る

出来上がったら一覧表示も作りたいのでboardsの中身身をコピペし部分ごとに編集していく

・# controllers/admin/users_controller.rb

class Admin::UsersController < Admin::BaseController
  before_action :login_user, only: %i[edit show update destroy]

  def index
    @search = User.ransack(params[:q]) # ↓ includeはしていない
    @users = @search.result(distinct: true).order(created_at: :desc).page(params[:page])
  end
...
  def update
    if @user.update(user_params)
      redirect_to admin_user_path, success: t('defaults.message.updated', item: User.model_name.human)
    else             # ↑ パスに注意                                               ↑ 各所翻訳も注意
      flash.now[:danger] = t('defaults.message.not_updated', item: User.model_name.human)
      render :edit
    end
  end

  def destroy
    @user.destroy!
    redirect_to admin_users_path, success: t('defaults.message.deleted', item: User.model_name.human)
  end             # ↑ パスに注意

  private

  def login_user
 ...

・ビュー


コントローラーでuserのidを取ってくることが出来たので、 boardと同じよう ・一覧(index),詳細(show),編集(edit)ページを作成する。 ・ファイルとフォルダは新たに作成しadmin下にすること。

一覧表示と言っても今までのページの表示ではなく管理者用のページなのでリスト化された物で良い 課題詳細にあったように

ユーザー一覧では、ID、フルネーム、権限(管理者 or 一般)の項目を表示

が出来れば良い。

しかし権限が一番大変

board同様に参考にするのは以下のBootstrap

Tables

Buttons

一覧画面(index)


・ # views/admin/users/index.html.erb

<%= content_for(:title, t('.title')) %>
  <h1><%= t('.title') %></h1>
<div class="col-lg-10 offset-lg-1">
  <!-- 検索フォーム -->
  <form>
  <%= render 'search_form', url: admin_users_path, search: @search %>
  </form>                           # ↑ パスに注意
...
  <tbody>
    <%= render @users %> #パーシャル作成
  </tbody>
</table>

boardと同じようにページネーションがあり、翻訳もしっかり充てられている

パーシャル部分


 # views/admin/users/_user.html.erb

...
  <th scope="row"><%= user.id %></th>
...
    <%= link_to user.decorate.full_name, admin_user_path(user) %>
...
    <%= user.role_i18n %> # 後述するrole_helpのgem
...
    <%= l user.created_at, format: :long %>
  ...
    <%= link_to t('defaults.delete'), admin_user_path(user), id: "button-delete-#{user.id}", class: "btn btn-danger",
        method: :delete, data: {confirm: t('defaults.message.d_confirm')} %>
    # パスに注意

検索のパーシャル


boardとほぼ同じだが、日付の代わりに入れた権限の:role_eq部分は後述

・# /views/admin/users/_search_form.html.erb

...
  <%= search_form_for search, url: url do |f| %>
  ...
        <%= f.search_field :first_name_or_last_name_cont, class: "form-control", placeholder:"検索ワード" %>
    ...
        <%= f.select :role_eq, User.roles_i18n.invert.map{|key, value| [key, User.roles[value]]}, { include_blank: t('defaults.not_select') }, class:"form-control" %>
...
<% end %> </div>

form_forで使用できるhtmlタグ

f.selectやf.date_selectを使うことで選択肢や日付選択ボックスを生成してくれる。 よく見かけるf.submitが送信ボタンの生成してくれる様に。

form_forの使い方をマスターしよう!

セレクトボックスの書き方は以下

【開発メモ】Ruby on Railsのform_forでドロップダウンリストの選択ボックスを設置する方法 | FREE SWORDER

詳細(show)


最初は権限がわからなかった(後述) レイアウトは元々のapp/views/profiles/show.html.erbを参照し権限の表示部分を追加

・自分の回答 # views/admin/users/show.html.erb

<%= content_for(:title, t('.title')) %>
...
      <%= link_to t('defaults.delete'), admin_user_path, id: 'button-delete-#{@user.id}', class: 'btn btn-danger float-right',
        method: :delete, data: {confirm: t('defaults.message.d_confirm')} %>  # この上下のlink_toは編集と削除ボタン
      <%= link_to t('defaults.edit'), edit_admin_user_path, id: "button-edit-#{@user.id}", class:"btn btn-success float-right" %>
... 
<%= User.human_attribute_name(:id) %> ... <%= User.human_attribute_name(:role) %> <td><%= @user.role_i18n %></td> # この権限を表示する部分に悩んだ ...
<%= User.human_attribute_name(:email) %></th> <%= @user.email %> ...
<%= User.human_attribute_name(:full_name) %> <%= @user.decorate.full_name %>
... <%= User.human_attribute_name(:avatar) %>

権限(role)

今回追加になった権限という部分をセレクトボックスを使い、更にi18n対応させるという課題

Gemfileに

gem 'enum_help'

を追加しbundle install 詳しいやり方は以下

【Rails】enum_helpを用いてi18n対応セレクトボックスを作成 - Qiita

編集(edit)

・# views/admin/users/edit.html.erb

      <%= form_with model: [:admin, @user], url: admin_user_path, local: true do |f| %>
        <%= render 'layouts/error_messages', object: f.object %>
          <%= f.label :email %>
          <%= f.email_field :email, class:"form-control" %>
          <%= f.label :last_name %>
          <%= f.text_field :last_name, class: "form-control" %>
...
          <%= f.label :first_name %>
          <%= f.text_field :first_name, class:"form-control" %>
 ...
          <%= f.label :avatar %>
          <%= f.file_field :avatar, onchange: 'previewImage()', class: 'form-control mb-3', accept: 'image/*' %>
          <%= f.hidden_field :avatar_cache %>
    ...
          <%= image_tag @user.avatar.url,
                        id: 'preview',
                        size: '100x100' %>
   ...
          <%= f.select :role, User.roles_i18n.invert, {}, class:"form-control" %>
          <%= f.submit class:"btn btn-primary" %>
 

モデル部分の記載が違ったがそれ以外はほぼ同じ。元々のadminじゃない方のeditフォームをコピペしたのであまり大差はない。

エラーメッセージのファイルは自分はlayoutsに入れてるのでエラーは出なかった