AdminLTE 3を使って管理者ページを実装しよう・2
この記事の続きです。
https://ryujisurf55.hatenablog.com/entry/2021/04/30/180846
手順
- 管理者用のコントローラーを作成
- ルーティングの設定
- ビューの設定
- ページタイトルの設定
1.管理者用のコントローラーを作成
まずはベースとなるadmin/base_controller.rb
を作成します。
#ターミナル
$ rails g controller admin::base
#app/controllers/admin/base_controller.rb
class Admin::BaseController < ApplicationController
before_action :check_admin
layout 'admin/layouts/application'
private
def not_authenticated
flash[:warning] = 'ログインして下さい'
redirect_to admin_login_path
end
def check_admin
redirect_to root_path, warning: '権限がありません' unless current_user.admin?
end
end
layout
で読み込みたいレイアウトを指定しています。このレイアウトは後で作成します。
check_adminメソッド
で管理者でない場合はトップページに遷移するようにしています。
次はこのbase_controller
を継承したログイン機能を有したコントローラーuser_sessions.rb
とトップーページの遷移を管理するdashboards_controller.rb
も作成していきます。
#ターミナル
$ rails g controller admin::user_sessin
$ rails g controller admin::dashboards
#app/controllers/admin/user_sessions_controller.rb
class Admin::UserSessionsController < Admin::BaseController
skip_before_action :check_admin, only: %i[new create]
skip_before_action :require_login, 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
これは管理者用のログイン画面です。
つまりログインしていない状態でもアクセスを可能にする必要があり
skip_before_action
を指定しているわけです。
#app/controllers/admin/dashboards_controller.rb
class Admin::DashboardsController < Admin::BaseController
def index; end
end
継承元のbase_controller.rb
でレイアウトファイルを指定しているのでここでは指定しません。
2.ルーティングの設定
#config/routes.rb
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
namespace
以下の場合はnamespaceが望ましい
- URLは指定のパスにしたい
- ファイル構成も指定のパスにしたい
今回のadmin
ではこちらが当てはまる為使用します。
/admin
から始まるURLにする事ができて分けて管理する事ができます。
3.ビューの設定
まずはレイアウトの作成
ディレクトリを作成とファイルの作成。
#ターミナル
$ mkdir app/views/layouts
$ touch app/views/layouts/application.html.erb
$ touch app/views/layouts/admin_login.html.erb
#app/views/layouts/application.html.erb
<!DOCTYPE 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 %>
<%= stylesheet_link_tag 'admin', media: 'all' %> #ここでadmin.scssを読み込む
<link href="<https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700>" rel="stylesheet">
</head>
<body class="hold-transition sidebar-mini layout-fixed">
<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>
<%= javascript_include_tag 'admin' %> #ここでadmin.jsを読み込む
</body>
</html>
#app/views/layouts/admin_login.html.erb
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="robots" content="noindex, nofollow">
<title><%= page_title(yield(:title), admin: true) %></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'admin', media: 'all' %> #ここでadmin.scssを読み込む
</head>
<body class="hold-transition login-page">
<div>
<%= render 'shared/flash_message' %>
<%= yield %>
</div>
</body>
</html>
ヘッダー・サイドバー・フッターのパーシャルを作成
admin/shared
ディレクトリを作成してパーシャルを作ります。
#ターミナル
$ mkdir app/views/admin/shared
$ touch app/views/admin/shared/_header.html.erb
$ touch app/views/admin/shared/_sidebar.html.erb
$ touch app/views/admin/shared/_footer.html.erb
#app/views/admin/shared/_header.html.erb
<!-- 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">
<li class="nav-item">
<%= link_to t('defaults.logout'), admin_logout_path, class: 'nav-link', method: :delete %>
</li>
</ul>
</nav>
<!-- /.navbar -->
#app/views/admin/shared/_sidebar.html.erb
<!-- 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>
<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>
#app/views/admin/shared/_footer.html.erb
<footer class="main-footer">
<strong>Copyright © 2019 RUNTEQ.</strong>
All rights reserved.
</footer>
ここまででレイアウトとパーシャルができました。
ログイン画面とトップページの作成
#ターミナル
$ app/admin/user_sessions/new.html.erb
$ app/admin/dashboards/index.html.erb
#app/admin/user_sessions/new.html.erb
<% content_for(:title, 'ログイン') %>
<div class="login-box">
<div class="login-logo">
<h1>ログイン</h1>
</div>
<!-- /.login-logo -->
<div class="card">
<div class="card-body login-card-body">
<%= form_with url: admin_login_path, local: true do |f| %>
<%= f.label :email, 'メールアドレス' %>
<div class="input-group mb-3">
<%= f.text_field :email, class: 'form-control', placeholder: 'メールアドレス' %>
<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>
#app/admin/dashboards/index.html.erb
<% content_for(:title, 'ダッシュボード') %>
<div class="container">
<div class="row">
ダッシュボードです
</div>
</div>
4.ページタイトルの設定
ページタイトルの設定は過去記事で触れているので宜しければ。
https://ryujisurf55.hatenablog.com/entry/2021/04/27/184802
#app/helpers/application_helper.rb
module ApplicationHelper
def page_title(page_title = '', admin = false)
base_title = if admin
'RUNTEQ BOARD APP(管理画面)'
else
'RUNTEQ BOARD APP'
end
page_title.empty? ? base_title : page_title + ' | ' + base_title
end
最後に
読んでいただいた方、ありがとうございました。