Ruby on Rails

Rails + AdminLTEで一覧画面を作成する

はじめに

Rubyの人気フレームワーク「Ruby on Rails」と、管理画面の制作でよく利用されるCSSの人気フレームワーク「AdminLTE」を利用して一覧画面、詳細画面、編集画面、登録画面を作成する手順を紹介します。

本記事では、一覧画面を作成しています。

[画面イメージ]

AdminLTE 一覧画面イメージ図

事前準備

AdminLTEの導入

AdminLTEの構築手順は下記の通り。

スポンサーリンク

Scaffoldで雛形を生成する

まずは便利な機能である「Scaffold」で、一覧、詳細、登録、更新画面の雛形を生成します。

rails g scaffold リソース名 カラム名1:データ型1 カラム名2:データ型2...

 

「Scaffold」で雛形を生成した後に、「migrate」でデータベースにテーブルを作成します。

PS C:\ruby\adminlte_sample> rails g scaffold user name:string address:text phone:string sex:integer mail_address:string email_permission:boolean
      invoke  active_record
      create    db/migrate/20200627230859_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      invoke  resource_route
       route    resources :users
      invoke  scaffold_controller
      create    app/controllers/users_controller.rb
      invoke    erb
      create      app/views/users
      create      app/views/users/index.html.erb
      create      app/views/users/edit.html.erb
      create      app/views/users/new.html.erb
      create      app/views/users/_form.html.erb
      invoke    test_unit
      create      test/controllers/users_controller_test.rb
      create      test/system/users_test.rb
      create      app/helpers/users_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/users/index.json.jbuilder
      create      app/views/users/show.json.jbuilder
      create      app/views/users/_user.json.jbuilder
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/users.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.scss
PS C:\ruby\test1> rails db:migrate
== 20200627230859 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0037s
== 20200627230859 CreateUsers: migrated (0.0085s) =============================

 

今回の例では、下記のテーブルを生成しています。

論理名 物理名 データ型
ユーザー名 name string
住所 address text
電話番号 phone string
性別 sex integer
メールアドレス mail_address string
メール受信許可 email_permission boolean

 

「Scaffold」で雛形を自動生成すると「css」も生成されます。今回はAdminLTEを利用するので、自動生成された app/assets/stylesheets/scaffolds.scss ファイルは削除してください。

レイアウトファイルの修正

共通レイアウト(application.html.erb)

AdminLTE 適用のサンプルとして付属してくる「node_modules/admin-lte/starter.html」から、必要な項目のみを抽出して「app/view/layouts/application.html.erb」へ反映します。

スポンサーリンク

 

[app/view/layouts/application.html.erb]

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="x-ua-compatible" content="ie=edge">

    <title>管理画面</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  
    <!-- Google Font: Source Sans Pro -->
    <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
    <!-- Ionicons -->
    <link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
  </head>

  <body class="hold-transition sidebar-mini">
    <div class="wrapper">
      <!-- Navbar -->
      <nav class="main-header navbar navbar-expand navbar-white navbar-light">
        <!-- ヘッダメニュー -->
        <ul class="navbar-nav">
          <li class="nav-item">
            <a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
          </li>
        </ul>
      </nav>
      <!-- /.navbar -->

      <!-- サイドバー -->
      <aside class="main-sidebar sidebar-dark-primary elevation-4">
        <!-- サイトロゴ -->
        <%= link_to "/users", class:"brand-link" do %>
          <span class="brand-text font-weight-light">管理画面</span>
        <% end %>

        <!-- Sidebar -->
        <div class="sidebar">

          <!-- 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 has-treeview menu-open">
                <a href="#" class="nav-link active">
                  <i class="nav-icon fas fa-edit"></i>
                  <p>
                    ユーザー管理
                    <i class="right fas fa-angle-left"></i>
                  </p>
                </a>
                <ul class="nav nav-treeview">
                  <li class="nav-item">
                    <%= link_to "/users", class:"nav-link" do %>
                      <i class="far fa-circle nav-icon"></i>
                      <p>ユーザー情報一覧</p>
                    <% end %>
                  </li>
                  <li class="nav-item">
                    <%= link_to new_user_path, class:"nav-link" do %>
                      <i class="far fa-circle nav-icon"></i>
                      <p>ユーザー新規登録</p>
                    <% end %>
                  </li>
                </ul>
              </li>
            </ul>
          </nav>
          <!-- /.sidebar-menu -->
        </div>
        <!-- /.sidebar -->
      </aside>

      <!-- メインコンテンツ -->
      <div class="content-wrapper">
        <%= yield %>
      </div>
      <!-- /.content-wrapper -->

      <!-- Main Footer -->
      <footer class="main-footer">
        <!-- To the right -->
        <div class="float-right d-none d-sm-inline">
          Anything you want
        </div>
        <!-- Default to the left -->
        <strong>Copyright &copy; 2020 All rights reserved.
      </footer>

    <!-- ./wrapper -->
    </div>
  </body>
</html>

 

application.html.erbは共通レイアウトであり、メインコンテンツは下記のように各画面のhtml.erbファイルで記述するようにしています。

<!-- メインコンテンツ -->
<div class="content-wrapper">
<%= yield %>
</div>

一覧画面(index.html.erb)

「node_modules/admin-lte/pages/tables/data.html」を参考に一覧画面の中身を作成していきます。

テーブルの表示は 「jQuery DataTables」プラグインを使用します。(※AdminLTEをインストールするとプラグインとして付与される)

 

[app/view/users/index.html.erb]

<p id="notice"><%= notice %></p>
<%= javascript_pack_tag 'users/index' %>

<!-- 上部 -->
<section class="content-header">
  <div class="container-fluid">
    <div class="row mb-2">
      <div class="col-sm-6">
        <h1>ユーザー情報一覧</h1>
      </div>
      <div class="col-sm-6">
        <ol class="breadcrumb float-sm-right">
          <li class="breadcrumb-item"><%= link_to 'ホーム' %></li>
          <li class="breadcrumb-item active">ユーザー情報一覧</li>
        </ol>
      </div>
    </div>
  </div><!-- /.container-fluid -->
</section>

<!-- テーブル -->
<section class="content">
  <div class="container-fluid">
    <div class="row">
      <div class="col-12">
        <div class="card">
          <!-- /.card-header -->
          <div class="card-body">
            <table id="users_example" class="table table-bordered table-hover">
              <thead>
                <tr>
                  <th style="width:15%;">名前</th>
                  <th>住所</th>
                  <th style="width:10%;">電話番号</th>
                  <th style="width:9%;">性別</th>
                  <th style="width:15%;">メール</th>
                  <th style="width:14%;">メール受信</th>
                  <th style="width:20%;"></th>
                </tr>
              </thead>
            
              <tbody>
                <% @users.each do |user| %>
                  <tr>
                    <td><%= user.name %></td>
                    <td><%= user.address %></td>
                    <td><%= user.phone %></td>
                    <td><% if user.sex == 0 then %>男<% else %>女<% end %></td>
                    <td><%= user.mail_address %></td>
                    <td><% if user.email_permission then %>許可<% else %>許可しない<% end %></td></td>
                    <td><%= link_to '詳細', user, class:"btn btn-outline-primary btn-sm" %>
                    <%= link_to '編集', edit_user_path(user), class:"btn btn-outline-primary btn-sm" %>
                    <%= link_to '削除', user, method: :delete, class:"btn btn-outline-danger btn-sm", data: { confirm: '本当によろしいでしょうか?' } %></td>
                  </tr>
                <% end %>
              </tbody>
            </table>
          </div>
          <!-- /.card-body -->
        </div>
        <!-- /.card -->
      </div>
      <!-- /.col -->
    </div>
    <!-- /.row -->
  </div>
  <!-- /.container-fluid -->
</section>
<!-- /.content -->

一覧画面のJSファイル(index.js)

「jQuery DataTables」を動作させるために「app/javascript/packs」配下に「users/index.js」を作成します。

そして「app/view/users/index.html.erb」に下記の記述を追記(2行目)し、作成したJavaScriptファイルを読み込むようにします。

<%= javascript_pack_tag 'users/index' %>

 

[app/javascript/packs/users/index.js]

import 'admin-lte/plugins/datatables/jquery.dataTables.min.js';
import 'admin-lte/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js';
import 'admin-lte/plugins/datatables-responsive/js/dataTables.responsive.min.js';
import 'admin-lte/plugins/datatables-responsive/js/responsive.bootstrap4.min.js';

$(function() {
    $('#users_example').DataTable({
        "paging": true,
        "lengthChange": true,
        "searching": true,
        "ordering": true,
        "info": true,
        "autoWidth": false,
        "responsive": true,
        "language":{ url: "http://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Japanese.json" }
    });
});

 

importで必要なjsファイル(node_modules/admin-lte/pages/tables/data.htmlで読み込んでいたjsファイル)を読み込み、$('#users_example').DataTableで「jQuery DataTables」プラグインを動作させるための設定をしています。

 

各項目の説明は下記の通り。

項目 説明
paging ページング機能
lengthChange 一覧に表示する件数を切り替える機能
searching 検索機能
ordering ソート機能
info 情報の表示
autoWidth 列幅の自動計算機能
responsive レスポンシブ機能
language 表示する言語

スポンサーリンク

その他

application.js

AdminLTEを使えるようにするために、application.jsに「require("admin-lte");」を追加しています。

[app/javascript/packs/application.js]

// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")

require("admin-lte");

// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)

environment.js

jQueryを動作させるために、environment.jsを下記のように修正しています。

[app/config/webpack/environment.js]

const { environment } = require('@rails/webpacker')

const webpack = require('webpack')

environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'admin-lte/plugins/jquery/jquery',
    jQuery: 'admin-lte/plugins/jquery/jquery'
  })
)

module.exports = environment

environment.toWebpackConfig().merge({
  resolve: {
  alias: {
    'jquery': 'admin-lte/plugins/jquery/jquery',
    }
  }
});

動作確認

最後にRailsのサーバーを起動して動作確認してみます。

rails s

 

「 http://localhost:3000/users 」にアクセスして次のように表示、そして、ソートなどの「jQuery DataTables」プラグインの機能が正常に動作すれば完了です。

AdminLTE 一覧画面イメージ図

 

終わりに

本記事では「Rails + AdminLTEで一覧画面を作成する方法」について紹介しました。

次回は、Rails + AdminLTEで「登録画面」を作成する方法について紹介します。

よろしければ記事の評価をお願いします

© 2020 ITを分かりやすく解説