Rails
rails_admin

RailsAdminを使ってみた

ウェブクルー Advent Calendar 2017 20日目の記事です!
昨日は@wc_orks さんの「正規表現で置換時にマッチした文字をそのまま使う」でした!

RailsAdminとは

  • 管理画面を簡単に実現する事ができるgem
  • デモサイトはこちら
  • 使うまでの楽さ:smiley:
  • 導入時点での機能:smiley:
  • カスタマイズのしやすさ:thinking:

Gemなどのバージョン

  • ruby 2.3
  • rails 5.1.4
  • mysql 5.7
  • rails_admin 1.2
  • device 4.3
  • cancan 2.1.2

dockerを使ってrailsプロジェクトを作成しています。
詳細は割愛させていただきますが、
記事の最後にgithubのリンクを貼っておくので、よろしければご覧ください。

導入

RailsAdminのインストール

rails g rails_admin:install

device設定

ユーザ管理にdeviceを利用するので設定を行います。
利用する機能はデフォルトのまま進めます。

rails g devise:install

メッセージが色々出るので、案内通りに設定します。
config/environments/development.rbに以下を設定

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

Pagesコントローラの作成

rails g controller Pages index show

/config/routes.rbに以下を追加

root to: "home#index"

app/views/layouts/application.html.erbに以下を追加

<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>

deviseを使ってviewやmodelを作成

rails g devise:views
rails g devise User
rails db:migrate

cancan

abilityの追加

rails g cancan:ability

usersテーブルにadmin列を追加

rails g migration AddColumnAdminToUser admin:boolean
rails db:migrate

users.adminに1をセット(SQLのupdate等で更新する)

UPDATE users SET admin=1;

models/ability.rbの以下をコメント外す

user ||= User.new # guest user (not logged in)
if user.admin?
    can :manage, :all
else
    can :read, :all
end

ここまでうまくできていれば以下の確認ができます。

  • ルートへのアクセス(localhost:3000)
  • /adminにアクセスしようとするとログイン画面が表示され、Sign Upボタン押下でユーザ登録が可能

少しカスタマイズしてみる

権限設定を行う

権限テーブル追加して、ability.rbで表示画面、実行可能アクションの制限

rails g model Role name:string
rails g migration AddColumnRoleToUser role_id:integer

models/user.rbに以下のようにbelongs_toでアソシエーションを追加

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  belongs_to :role
end

models/role.rbに以下のようにhas_manyでアソシエーションを追加

class Role < ApplicationRecord
    has_many :users
end

変更の反映

rails db:migrate
rails restart

以下のようにRolesにデータを追加

INSERT INTO `roles` (`id`, `name`, `created_at`, `updated_at`)
VALUES
    (1,'admin','2017-12-14 14:42:06','2017-12-14 14:42:06'),
    (2,'manager','2017-12-14 14:42:14','2017-12-14 14:42:14'),
    (3,'leader','2017-12-14 14:42:30','2017-12-14 14:42:30'),
    (4,'developer','2017-12-14 14:42:45','2017-12-14 14:42:45');

ついでにusersの更新も行う

UPDATE users SET role_id = 3;

特定のテーブルの参照/更新権限などの確認を行うため、
適当にテーブルを追加

rails g model item name:string price:integer 
rails db:migrate
rails restart

データをこんな感じで入れておきましょう。

INSERT INTO `items` (`id`, `name`, `price`, `created_at`, `updated_at`)
VALUES
    (1,'ビール',500,'2017-12-14 14:59:20','2017-12-14 14:59:28');

それでは実際に権限設定を行っていきます。

models/ability.rbを以下のように設定

class Ability
  include CanCan::Ability

  def initialize(user)
      if user
        can :access, :rails_admin
        can :dashboard, :all
      end
      if user.admin?
        can :manage, :all
      end

      if user.role_id == 2
        can [:read,:new,:update,:create,:export,:import], [Item]
      end
      if user.role_id == 3
        can [:read,:new,:update,:create], [Item]
      end
      if user.role_id == 4
        can [:read], [Item]
      end

  end
end

ここまで行えば、ユーザの権限に対する画面表示等が可能となります。

日本語化と表示項目の設定

rails_admin.rbを使った日本語化

config.model 'ModelName' doで対象テーブルの項目表示設定を行います。
表示したい項目を設定していくやり方、include_all_fieldsで全ての項目を表示するやり方等があります。
この辺りはwikiに記載されています。

config/initializers/rails_admin.rb

RailsAdmin.config do |config|

    ## == Devise ==
    config.authenticate_with do
      warden.authenticate! scope: :user
    end
    config.current_user_method(&:current_user)

    ## == Cancan ==
    config.authorize_with :cancan

    config.actions do
      dashboard                     # mandatory
      index                         # mandatory
      new
      export
      bulk_delete
      show
      edit
      delete
      show_in_app
    end

    config.model 'User' do
      LABEL_id = 'ユーザID'
      LABEL_email = 'メールアドレス'
      LABEL_admin = '管理者フラグ'
      LABEL_role = '権限'
      LABEL_created_at = '作成日時'
      LABEL_updated_at = '更新日時'

      # ここに指定した項目が表示される。include_all_fieldsをすれば全て表示。
      list do
        field :id do
          label LABEL_id
        end
        field :email do
          label LABEL_email
        end
        field :admin do
          label LABEL_admin
        end
        include_fields :role do
          label LABEL_role
        end
        field :created_at do
          label LABEL_created_at
        end
        field :updated_at do
          label LABEL_updated_at
        end
      end
    end

    config.model 'Role' do
      LABEL_id = '権限ID'
      LABEL_name = '権限名'
      LABEL_created_at = '作成日時'
      LABEL_updated_at = '更新日時'
      list do
        field :id do
          label LABEL_id
        end
        field :name do
          label LABEL_name
        end
        field :created_at do
          label LABEL_created_at
        end
        field :updated_at do
          label LABEL_updated_at
        end
      end
      show do
        field :id do
          label LABEL_id
        end
        field :name do
          label LABEL_name
        end
        field :created_at do
          label LABEL_created_at
        end
        field :updated_at do
          label LABEL_updated_at
        end
      end
      create do
        field :name do
          label LABEL_name
          # helpを指定することにより、項目説明を入れることが可能
          help "最大文字数: 255"
        end
      end
      update do
        field :id do
          label LABEL_id
          read_only true
          help ""
        end
        field :name do
          label LABEL_name
          help "最大文字数: 255"
        end
      end
    end 
  end

上記に加えてusersのここまで設定できれば、ユーザの権限に対応する画面表示ができるようになります。

/locales/ja.ymlを使った共通項目の日本語化

  • wikiのJapaneseのリンクから内容をコピーし、config/locales/ja.ymlを作成します
  • config/application.rbに以下のコードを追加します
config.i18n.default_locale = :ja

csvインポート機能の追加

Gemfileに以下を追加し、bundle install

gem "rails_admin_import", "~> 2.1"

rails_admin.rbのconfig.actionsにimportを追加

    config.actions do
      dashboard                     # mandatory
      index                         # mandatory
      new
      export
      bulk_delete
      show
      edit
      delete
      show_in_app
      # importを追加することにより、CSVインポートが可能となる
      import
    end

まとめ

以上、RailsAdminの機能を使って管理ツールを作成してみました。
導入時点でCRUDとCSVダウンロード/アップロードの機能を使えるようになるため、
チーム内で利用する際には便利だと思います。
deviceとcancanを組み合わせる事によって認証機能を作れちゃうのも素晴らしいですね。

ただし画面構成を変えたり、RailsAdminが用意していない項目や機能を追加するならば、
ActiveAdminなど他のgemを利用した方が良いかもしれませんね。

明日の担当は@morotin さんです!よろしくお願いします!

github

https://github.com/da-shi/catchup/tree/master/RailsAdmin

参考にさせていただいたページ

本家のWiki
[Rails] deviseの使い方(rails5版)