14. admin ユーザの作成

さまざまな権限の元で開発ができるように、すべての権限に化けられる SuperUser アカウントである admin を作成する。このアカウントは LDAP アクセスできない環境でも作業できるようにローカルアカウントとする。ただし、Devise 1.1.2 の頃と属性データの互換性がないため、ダンプデータからの流し込みはせず、スクリプトで作成することにする。

まず、Admin モデルを作成する。

$ bin/rails g devise Admin
      invoke  active_record
      create    db/migrate/20141227202954_devise_create_admins.rb
      create    app/models/admin.rb
      invoke    rspec
      create      spec/models/admin_spec.rb
      invoke      factory_girl
      create        spec/factories/admins.rb
      insert    app/models/admin.rb
       route  devise_for :admins

今回は、旧システムと同期を考えなくてよいこと、データはスクリプトで作成することから、Rememberable と Trackable 以外の機能は付けないこととする。DeviseCreateAdmins で修正した部分は以下の通り(name 属性の追加、必要ない機能の削除)。

      t.string :name,               null: false, default: ""
      # t.string   :reset_password_token
      # t.datetime :reset_password_sent_at
    #add_index :admins, :email,                 unique: true
    add_index :admins, :name,                   unique: true
    # add_index :admins, :reset_password_token, unique: true

app/models/admin.rb も機能に合わせて修正する。

# @!attribute encrypted_password
#   @return [String] 暗号化されたパスワード
# @!attribute remember_created_at
#   @return [DateTime] パスワード記憶の日付
# @!attribute sign_in_count
#   @return [FixNum] サインイン数
# @!attribute current_sign_in_at
#   @return [DateTime] 現在のサインイン日付
# @!attribute last_sign_in_at
#   @return [DateTime] 最後にサインインした日付
# @!attribute current_sign_in_ip
#   @return [IPAddr] 現在のサインインIP
# @!attribute last_sign_in_ip
#   @return [IPAddr] 最後にサインインしたIP
# @!attribute name
#   @return [String] ログイン名
# @!attribute email'
#   @return [String] 電子メールアドレス
class Admin < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  # :registerable, :recoverable, :validatable
  devise :database_authenticatable, :rememberable, :trackable
end

設定が終了したので、キーボードからパスワードを入力し、Admin ユーザを作成する rake タスクを作成する。また同時に削除するタスクも同時に記述しておく。ここで、Admin ユーザは name が admin に固定で一つのアカウントのみとする。lib/tasks/admin_user.rake は以下のように記述した。

require 'io/console'

namespace :admin_user do
  desc "Admin user を作成"

  task add: :environment do
    admin = Admin.first
    if admin
      puts "admin ユーザはすでに作成済みです。"
    else
      print "Password: "
      password = STDIN.noecho(&:gets).chomp
      admin = Admin.create(name: 'admin', password: password, password_confirmation: password)
      puts “\nadmin ユーザを作成しました。"
    end
  end

  desc "Admin user を削除"

  task remove: :environment do
    admin = Admin.first
    if admin
      Admin.first.destroy
      puts "admin ユーザを削除しました。"
    else
      puts "admin ユーザは作成されていません。"
    end
  end
end

正しく登録されたか、rake -vT で確認する。

$ rake -vT
rake about                              # List versions of all Rails framew...
rake admin_user:add                     # Admin user を作成
rake admin_user:remove                  # Admin user を削除
(以下略)

実際にテストしてみる。

$ bin/rake admin_user:add
Password: 
admin ユーザを作成しました。
$ bin/rake admin_user:add
admin ユーザはすでに作成済みです。
$ bin/rake admin_user:remove
admin ユーザを削除しました。
$ bin/rake admin_user:remove
admin ユーザは作成されていません。

四つのパターンがすべて試せたので、ちゃんとユーザを作成しておく。

これで admin のログインページに行ってログインできることを確認してみる。ログインできたところで、Welcome#index に飛ぶが、user でログインしていないため、before_action :authenticate_user! に引っかかり、users/sign_in にリダイレクトされてしまう。

これを回避するために、app/controllers/application_controller.rb に以下のオーバライドメソッドを記述する(参考:Devise login with user or admin models and Basecamp style subdomains

  def authenticate_user!
    return if admin_signed_in?
    super
  end

これで無事に welcome#index が描画された。

admin のモデルは基本機能のみで特にテストをする予定はないので、spec/admin_spec.rb は削除しておく。

今日はここまで。