Railsで管理画面 - ユーザー 編
前回の続き
・コントローラー
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
一覧画面(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が送信ボタンの生成してくれる様に。
セレクトボックスの書き方は以下
【開発メモ】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に入れてるのでエラーは出なかった