💡
この記事は Middleman 時代に書いた古いものです。記録のため、astro-notion-blog に移行していますが、あまり参考にしないでください。
Rails でログイン機能を実現する場合には,devise という gem を使う. 学内であれば,ldap 認証ができるので,devise-ldap-authentication を使うことが多いのだが,今回は通常のローカル認証での設定を行う. 今回のログイン対象のクラスは Teacher である.
devise のインストール
-
まず Gemfile に devise を追加する.
gem 'devise'
-
bundle する(2行目以降は結果: 追加分のみ)
$ bundle Fetching bcrypt 3.1.12 Fetching orm_adapter 0.5.0 Fetching warden 1.2.7 Installing orm_adapter 0.5.0 Installing warden 1.2.7 Installing bcrypt 3.1.12 with native extensions Fetching responders 2.4.0 Installing responders 2.4.0 Fetching devise 4.5.0 Installing devise 4.5.0
-
rails の generator で devise を install する
$ bin/rails g devise:install Running via Spring preloader in process 80494 create config/initializers/devise.rb create config/locales/devise.en.yml =============================================================================== Some setup you must do manually if you haven't yet: 1. Ensure you have defined default url options in your environments files. Here is an example of default_url_options appropriate for a development environment in config/environments/development.rb: config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } In production, :host should be set to the actual host of your application. 2. Ensure you have defined root_url to *something* in your config/routes.rb. For example: root to: "home#index" 3. Ensure you have flash messages in app/views/layouts/application.html.erb. For example: <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> 4. You can copy Devise views (for customization) to your app by running: rails g devise:views ===============================================================================
-
最後に表示されていたメッセージに従い処理を続ける.まず,config/environments/development.rb に URL オプションを指定する.
Rails.application.configure do config.action_mailer.default_url_options = {host: 'localhost', port: 3000} (中略) end
-
2 の root_url はすでに処理済である.3 はすでに haml にしているので,app/views/layouts/application.html.haml に追記する.
%html (中略) %body %p.notice= notice %p.alert= alert
-
4 の devise の view を作成しようとしたところ,次のようなエラーになった(2行目以降は結果)
$ bin/rails g devise:views /Users/hkob/rails/attendance/vendor/bundle/ruby/2.5.0/gems/railties-5.2.1/lib/rails/railtie/configuration.rb:97:in `method_missing': undefined method `action_mailer' for #<Rails::Application::Configuration:0x00007f81f001ba98> (NoMethodError) (後略)
-
action_mailer が Undefined と言われている.調べてみると,config/application.rb で action_mailer/railtie がコメントされていた.とりあえず以下のようにコメントを外した.
require_relative 'boot' require "rails" # Pick the frameworks you want: require "active_model/railtie" require "active_job/railtie" require "active_record/railtie" # require "active_storage/engine" require "action_controller/railtie" require "action_mailer/railtie"
-
再度,view を作成すると,無事にファイルが生成された(2行目以降は結果)
$ bin/rails g devise:views Running via Spring preloader in process 98994 invoke Devise::Generators::SharedViewsGenerator create app/views/devise/shared create app/views/devise/shared/_links.html.erb invoke form_for create app/views/devise/confirmations create app/views/devise/confirmations/new.html.erb create app/views/devise/passwords create app/views/devise/passwords/edit.html.erb create app/views/devise/passwords/new.html.erb create app/views/devise/registrations create app/views/devise/registrations/edit.html.erb create app/views/devise/registrations/new.html.erb create app/views/devise/sessions create app/views/devise/sessions/new.html.erb create app/views/devise/unlocks create app/views/devise/unlocks/new.html.erb invoke erb create app/views/devise/mailer create app/views/devise/mailer/confirmation_instructions.html.erb create app/views/devise/mailer/email_changed.html.erb create app/views/devise/mailer/password_change.html.erb create app/views/devise/mailer/reset_password_instructions.html.erb create app/views/devise/mailer/unlock_instructions.html.erb
-
作成されたファイルは erb なので,以前のように haml に変換しておく.
$ env HAML_RAILS_DELETE_ERB=true bin/rails haml:erb2haml
Teacher モデルの作成
-
devise の設定が終わったので,Teacher モデルを devise によって作成する.
$ bin/rails g devise Teacher Running via Spring preloader in process 99389 invoke active_record create db/migrate/20181108090734_devise_create_teachers.rb create app/models/teacher.rb insert app/models/teacher.rb route devise_for :teachers
-
app/models/teacher.rb は以下のようになっている.デフォルトで設定されている項目は以下の通りである.
- database_authenticatable: データベースに暗号化されたパスワードを保存する
- registerable: 登録処理できるようにする
- recoverable: パスワードリセットできるようにする
- rememberable: クッキーにログイントークンを保存する
- validatable: パスワードのバリデーションを行う
class Teacher < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable end
-
db/migrate/20181108090734_devise_create_teachers.rb は以下のようになっている.
# frozen_string_literal: true class DeviseCreateTeachers < ActiveRecord::Migration[5.2] def change create_table :teachers do |t| ## Database authenticatable t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable # t.integer :sign_in_count, default: 0, null: false # t.datetime :current_sign_in_at # t.datetime :last_sign_in_at # t.inet :current_sign_in_ip # t.inet :last_sign_in_ip ## Confirmable # t.string :confirmation_token # t.datetime :confirmed_at # t.datetime :confirmation_sent_at # t.string :unconfirmed_email # Only if using reconfirmable ## Lockable # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts # t.string :unlock_token # Only if unlock strategy is :email or :both # t.datetime :locked_at t.timestamps null: false end add_index :teachers, :email, unique: true add_index :teachers, :reset_password_token, unique: true # add_index :teachers, :confirmation_token, unique: true # add_index :teachers, :unlock_token, unique: true end end
-
LDAP 認証の場合にはアカウント名を追加し,認証もそのアカウントで行うことになる.今回は,ローカル認証だけなのでデフォルトの e-mail でのログインとし,name 属性のみを追加するだけとする.そこで,上記 migrate ファイルに name だけを追加する.
t.string :name, null: false
-
データベースを migrate する(2行目以降は結果)
$ bin/rails db:migrate == 20181108090734 DeviseCreateTeachers: migrating ============================= -- create_table(:teachers) -> 0.0199s -- add_index(:teachers, :email, {:unique=>true}) -> 0.0112s -- add_index(:teachers, :reset_password_token, {:unique=>true}) -> 0.0022s == 20181108090734 DeviseCreateTeachers: migrated (0.0335s) ====================
ビューの部分が終わっていないが今日はここまで