##手順
1.AdminLTE3をインストール
2.管理者画面用のマニフェストファイルの設定
3.管理者権限を判定する為のカラムを追加
4.管理者用のコントローラー作成
5.ルーティングの設定
6.ビューファイルの作成
##1.AdminLTE3をインストール
AdminLTE3
とは、Bootstrap3をベースにした、管理画面等のテンプレートテーマ。
今回はyarn
を使ってAdminLTE3
をインストールする。
ターミナルにて**yarn add admin-lte@^3.1
**を実施。
するとnode_modules
/package.json
/yarn.lock
というファイルが生成される。
多数テンプレートファイルが用意されているので、その中のnode_modules/admin-lte/starter.html
を参照。
読み込むべきCSSファイル・JSファイルが記載されているので、これを参照しながらadmin.scss
、admin.js
2つのマニュフェストファイルを作成。
マニフェストファイルというのは、どのCSSファイルやJavascriptファイルを呼び出すかを記載したファイルのこと。
##2.管理者画面用のマニフェストファイルの設定
今まで一般ユーザー用のマニフェストファイルは
app/assets/javascripts/application.js
と
app/assets/stylesheets/application.scss
だったが、
管理者画面は一般ユーザーの画面と構成や見た目が大きく異なる事から、別々に管理するのが一般的なのでその設定をしていく。
まずはjsファイルから設定していく。
#この1文を削除
//= require_tree .
#admin.jsを作成し、以下を追記
//= require jquery3
//= require jquery_ujs
//= require admin-lte/plugins/bootstrap/js/bootstrap.bundle.min
//= require admin-lte/dist/js/adminlte.min
# これは必要ない → //= require admin-lte/plugins/jquery/jquery.min
#これはjQuery本体を読み込む記述なので、Gemfileに記述してインストールしているgemのjquery-railsと重複しているので不要
require_tree
には以下の特徴がある。
■指定したディレクトリ以下のすべてのJSファイルを読み込む
require_tree .
の場合は同じ階層以下すべてのJSファイルを読み込むということ。
■読み込む順序は指定できない。
そのため、利用しているJSファイルが特定の読み込み順に依存している場合に不都合がある。
今回はapplication.js
と同じ階層にadmin.js
を作成したので、application.js
でrequire_tree .
してしまうと、application.js
でadmin.js
を読み込んでしまう。
つまり管理画面でしか使わないはずのファイルまで、application.js
で読み込んでしままう。それを避けるためにrequire_tree .
は使わずに、ファイルを、個別に必要な順序で読み込む必要がある。
次にscssファイルを設定。
#以下の2文を追加
@import 'admin-lte/plugins/fontawesome-free/css/all.min.css';
@import 'admin-lte/dist/css/adminlte.css';
application
以外のマニフェストファイルを個別に読み込む場合は、プリコンパイルの設定をしないと、そのファイルは対象外とされてしまうためエラーが起きてしまうので、その設定も行う。
プリコンパイルとは、「事前に(pre)」コンパイルを行うこと。
コンパイルとは、SCSS等ブラウザが直接は読めない形式のファイルを、JSやCSSに変換してあげるということ。
何に対して「事前」かというと、**「rails serverが走るよりも前」**に該当する。
#この1行がコメントアウトされいるので、表示させる
Rails.application.config.assets.precompile += %w( admin.js admin.css )
##3.管理者権限を判定する為のカラムを追加
管理者権限を判定するカラムを今回は、一般ユーザと管理者を区別し、整数のinteger型
でroleカラム
を追加する。
ターミナルでrails g migration add_to_role_users
を実行。
class AddRoleToUsers < ActiveRecord::Migration[5.2]
def change
add_column :users, :role, :integer, default: 0, null: false
#↑一般ユーザが0・管理者は1とし、デフォルトは一般ユーザである0と指定
end
end
usersモデル
にenum
の設定をしていく。一般ユーザーをgeneral
、管理者をadmin
として定義。
#この1文を追記
enum role: { general: 0, admin: 1 }
##4.管理者用のコントローラー作成
管理者用のコントローラ-を作成するにあたって、「管理系」のカテゴリとして区分したいため、Admin::BaseController
という名前で作成。
この名前は、Admin
というモジュールの名前空間の中にBaseController
というクラスを定義するという意味になる。
Rails
ではモジュール階層を、コードを保存するためのディレクトリ階層に対応させているので、admin/base_controller.rb
というファイルが対応する事になる。
後々、管理系の機能を増やす時に、Admin::
のついたコントローラーを追加していけば、コードがadmin
ディレクトリ配下にまとまるので視認性が良くなる。
rails g controller Admin::Base
#↓管理者用のトップページ用のコントローラーを作成
rails g controller Admin::Dashboards index
#↓管理者用のログイン用のコントローラーを作成
rails g controller Admin::User_sessions
ではコントローラーの中身を記述していく。
管理者機能の根幹となるAdmin::BaseController
に
class Admin::BaseController < ApplicationController
bofore_action :check_admin
#↓layout宣言
layout 'admin/layouts/application'
private
def not_authenticated
redirect_to admin_login_path, warning: "ログインしてください"
end
#↓管理者権限を持っているか確認する
def check_admin
redirect_to root_path, warning: "管理者権限を持っていません" unless current_user.admin?
end
end
通常、何も指定が無ければコントローラーはapp/views/layouts/application.html.erb
をレイアウトとして探索する。
管理者機能の根幹クラスであるAdmin::BaseController
で個別の管理者用画面のレイアウトファイルを呼び込むようにlayout宣言がいる。
class Admin::UserSessionsController < Admin::BaseController
skip_before_action :require_login, only: %i[new create]
skip_before_action :check_admin, only: %i[new create]
# ↓ログインページ用のレイアウトを用意するので宣言
layout 'admin/layouts/admin_login'
def new; end
def create
@user = login(params[:email], params[:password])
if @user
redirect_to admin_root_path , success: 'ログインしました'
else
flash.now[:danger] = 'ログインに失敗しました'
render :new
end
end
def destroy
logout
redirect_to admin_login_path, success: 'ログアウトしました'
end
end
Admin::UserSessionsコントローラー
もAdmin::Baseコントローラー
を継承してるで、そのままではadmin/layouts/application
をレイアウトとして使用する。
しかしログイン画面は違う見た目にするので、別のログインページ用のレイアウトファイルを用意してlayout宣言をする必要がある。
また、ログインしていないユーザや、管理者権限のないユーザでも、ログイン画面が表示されるようにskip_before_action
でフィルタをスキップさせる。
ログインした後はadmin_root_path
へリダイレクトされ、admin/dashboards#index
が呼び出される。
このとき、管理者ではない一般ユーザでログインした場合は、before_action :check_admin
フィルタによって、一般ユーザ用のトップページへリダイレクトされる。
##5.ルーティングの設定
Admin
モジュールの名前空間を使用したコントローラを作成したので、それに対応するようにルーティングにも名前空間を設定。
namespace :admin do
root to: 'dashboards#index'
get 'login', to: 'user_sessions#new'
post 'login', to: 'user_sessions#create'
delete 'logout', to: 'user_sessions#destroy'
end
##6.ビューファイルの作成
starter.html
から流用してレイアウトファイルを作成。
管理者画面用のマニフェストファイルadmin.scss
とadmin.js
を読み込む記述を忘れずに注意。
<!DOCTYPE html>
<html>
<html>
<head>
<meta charset="utf-8">
<meta lang='ja'>
<meta name="robots" content="noindex, nofollow">
<title><%= page_title(yield(:title), admin: true) %></title>
<%= csrf_meta_tags %>
# ↓ここでadmin.scssを読み込む
<%= stylesheet_link_tag 'admin', media: 'all' %>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
</head>
<body class="hold-transition sidebar-mini">
<div class="wrapper">
<%= render 'admin/shared/header' %>
<%= render 'admin/shared/sidebar' %>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<%= render 'shared/flash_message' %>
<%= yield %>
</div>
<!-- /.content-wrapper -->
<%= render 'admin/shared/footer' %>
</div>
# ↓ここでadmin.jsを読み込む
<%= javascript_include_tag 'admin' %>
</body>
</html>
・ヘッダー
<!-- Navbar -->
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
<!-- Left navbar links -->
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a>
</li>
</ul>
<!-- Right navbar links -->
<ul class="navbar-nav ml-auto">
<!-- Navbar Search -->
<li class="nav-item">
<%= link_to t('defaults.logout'), admin_logout_path, method: :delete, class: 'nav-link' %>
</li>
</ul>
</nav>
<!-- /.navbar -->
・フッター
<!-- Main Footer -->
<footer class="main-footer">
<strong>Copyright © 2022 SUMPLE.</strong>
All rights reserved.
</footer>
・サイドバー
<!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-primary elevation-4">
<!-- Brand Logo -->
<a href="index3.html" class="brand-link">
<%= image_tag 'AdminLTELogo.png', class: 'brand-image img-circle elevation-3' %>
<span class="brand-text font-weight-light">AdminLTE 3</span>
</a>
<!-- Sidebar -->
<div class="sidebar">
<!-- Sidebar user panel (optional) -->
<div class="user-panel mt-3 pb-3 mb-3 d-flex">
<div class="image">
<%= image_tag current_user.avatar_url, class: 'img-circle elevation-2' %>
</div>
<div class="info">
<a href="#" class="d-block"><%= current_user.decorate.full_name %></a>
</div>
</div>
<!-- Sidebar Menu -->
<nav class="mt-2">
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
<li class="nav-item">
<%= link_to '#', class: "nav-link" do %>
<i class="nav-icon far fa-file"></i>
<p>
掲示板一覧
</p>
<% end %>
<li class="nav-item">
<%= link_to '#', class: "nav-link" do %>
<i class="nav-icon far fa-user"></i>
<p>
ユーザ一一覧
</p>
<% end %>
</li>
</ul>
</nav>
<!-- /.sidebar-menu -->
</div>
<!-- /.sidebar -->
</aside>
・管理者ログイン画面
adminログインフォームのテンプレートはnode_modules/admin-lte/pages/example/login.html
を参考に作成。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title><%= page_title(yield(:title), admin: true) %></title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
# ↓admin.scssを読み込む
<%= stylesheet_link_tag 'admin', media: 'all' %>
</head>
<body class="hold-transition login-page">
<div>
<%= render 'shared/flash_message' %>
<%= yield %>
</div>
</body>
</html>
<%= content_for(:title, t('.title')) %>
<div class="login-box">
<div class="login-logo">
<h1><%= t('.title') %></h1>
</div>
<!-- /.login-logo -->
<div class="card">
<div class="card-body login-card-body">
<%= form_with url: admin_login_path, locale: true do |f| %>
<%= f.label :email, User.human_attribute_name(:email) %>
<div class="input-group mb-3">
<%= f.email_field :email, class: 'form-control', placeholder: 'Email'%>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-envelope"></span>
</div>
</div>
</div>
<%= f.label :password, User.human_attribute_name(:password) %>
<div class="input-group mb-3">
<%= f.password_field :password, class: 'form-control', placeholder: :password %>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<%= f.submit t('defaults.login'), class: 'btn btn-block btn-primary' %>
</div>
</div>
<% end %>
</div>
</div>
</div>
・管理者画面用トップページ
<%= content_for(:title, t('.title')) %>
<div class="content-wrapper">
<div class="row">
<p>ダッシュボードです</p>
</div>
</div>
管理画面用のページタイトルの設定
管理者画面が出ている時だけ、ページタイトルの末尾に(管理画面)
と表記させる。
module ApplicationHelper
def page_title(page_title = '', admin = false)
base_title = if admin
'SAMPLE BOARD APP(管理画面)'
else
'SAMPLE BOARD APP'
end
page_title.empty? ? base_title : page_title + ' | ' + base_title
end
end
この設定で、デフォルトをadmin = false
とすることによって、既存の一般ファイルに影響が出ないようにし、管理者用レイアウトファイルでadmin: true
を設定しておくことで、ページタイトルに(管理画面)
がつく。
(このadmin: trueの部分のこと。
<title><%= page_title(yield(:title), admin: true) %></title>
)
##参考記事
[Rails] AdminLTEを使って管理画面機能を作成
Ruby on Rails プリコンパイル という言葉の定義は?