私の歴史と今

振り返ると恥ずかしくなるのが私の歴史。だけどそのときは真面目に書いていた訳でね。そんな今の私を書いていく。

Railsでユーザ認証用にdeviseを使う

仕事ではいつも要件が合わなくてdeviseを使えないので、自分用にひと通り触ってみる。

rails new portal -T -d mysql

Gemfileに以下を追加して

gem 'devise'

以下を実行

bundle install

最新は2.0.4のようだ。

Installing orm_adapter (0.0.7)
Installing warden (1.1.1)
Installing devise (2.0.4)

以下のようにdeviseをrailsにインストール

D:\RailsProjects\portal>rails g devise:install
      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: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. If you are deploying Rails 3.1 on Heroku, you may want to set:

       config.assets.initialize_on_precompile = false

     On config/application.rb forcing your application to not access the DB
     or load models when precompiling your assets.

===============================================================================

上から順番に、まず、development.rbに以下を追加。(production環境は決まってないのでまたあとで)

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

次に、ルートとなるコントローラ&アクションをroutes.rbに設定する。

root :to => "front/auth#index"

最後に、views/layout/application.html.erbに以下のHTMLを追加。

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

※Herokuにはアップしない。

ここでMySQLのユーザを作成し、database.ymlに接続用の設定をしておく。

create user 'portal_user'@'localhost' identified by 'portal_passwd';
grant all privileges on portal_development.* to 'portal_user'@'localhost';
grant all privileges on portal_test.* to 'portal_user'@'localhost';
grant all privileges on portal_production.* to 'portal_user'@'localhost';
development:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: portal_development
  pool: 5
  username: portal_user
  password: portal_passwd
  host: localhost

DBを作成する。

D:\RailsProjects\portal>rake db:create --trace
** Invoke db:create (first_time)
** Invoke db:load_config (first_time)
** Invoke rails_env (first_time)
** Execute rails_env
** Execute db:load_config
** Execute db:create

ユーザ用のモデルクラスとマイグレーションファイルを作成する。

D:\RailsProjects\portal>rails g devise user
     invoke  active_record
     create    db/migrate/20120412165647_devise_create_users.rb
     create    app/models/user.rb
     insert    app/models/user.rb
      route  devise_for :users

すべての機能を使いたいのでマイグレーションファイルを編集する。

class DeviseCreateUsers < ActiveRecord::Migration
  def change
    create_table(:users) 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
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip

      ## Encryptable
      t.string :password_salt

      ## 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 # Only if lock strategy is :failed_attempts
      t.string   :unlock_token # Only if unlock strategy is :email or :both
      t.datetime :locked_at

      ## Token authenticatable
      t.string :authentication_token


      t.timestamps
    end

    add_index :users, :email,                :unique => true
    add_index :users, :reset_password_token, :unique => true
    add_index :users, :confirmation_token,   :unique => true
    add_index :users, :unlock_token,         :unique => true
    add_index :users, :authentication_token, :unique => true
  end
end

マイグレートする。

D:\RailsProjects\portal>rake db:migrate --trace
** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke db:load_config (first_time)
** Invoke rails_env (first_time)
** Execute rails_env
** Execute db:load_config
** Execute db:migrate
==  DeviseCreateUsers: migrating ==============================================
-- create_table(:users)
   -> 0.0625s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0469s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0625s
-- add_index(:users, :confirmation_token, {:unique=>true})
   -> 0.0469s
-- add_index(:users, :unlock_token, {:unique=>true})
   -> 0.0625s
-- add_index(:users, :authentication_token, {:unique=>true})
   -> 0.0469s
==  DeviseCreateUsers: migrated (0.3281s) =====================================

** Invoke db:_dump (first_time)
** Execute db:_dump
** Invoke db:schema:dump (first_time)
** Invoke environment
** Invoke db:load_config
** Execute db:schema:dump

DBを覗くとこんなテーブルができていた。

mysql> desc users;
+------------------------+--------------+------+-----+---------+----------------+
| Field                  | Type         | Null | Key | Default | Extra          |
+------------------------+--------------+------+-----+---------+----------------+
| id                     | int(11)      | NO   | PRI | NULL    | auto_increment |
| email                  | varchar(255) | NO   | UNI |         |                |
| encrypted_password     | varchar(255) | NO   |     |         |                |
| reset_password_token   | varchar(255) | YES  | UNI | NULL    |                |
| reset_password_sent_at | datetime     | YES  |     | NULL    |                |
| remember_created_at    | datetime     | YES  |     | NULL    |                |
| sign_in_count          | int(11)      | YES  |     | 0       |                |
| current_sign_in_at     | datetime     | YES  |     | NULL    |                |
| last_sign_in_at        | datetime     | YES  |     | NULL    |                |
| current_sign_in_ip     | varchar(255) | YES  |     | NULL    |                |
| last_sign_in_ip        | varchar(255) | YES  |     | NULL    |                |
| password_salt          | varchar(255) | YES  |     | NULL    |                |
| confirmation_token     | varchar(255) | YES  | UNI | NULL    |                |
| confirmed_at           | datetime     | YES  |     | NULL    |                |
| confirmation_sent_at   | datetime     | YES  |     | NULL    |                |
| unconfirmed_email      | varchar(255) | YES  |     | NULL    |                |
| failed_attempts        | int(11)      | YES  |     | 0       |                |
| unlock_token           | varchar(255) | YES  | UNI | NULL    |                |
| locked_at              | datetime     | YES  |     | NULL    |                |
| authentication_token   | varchar(255) | YES  | UNI | NULL    |                |
| created_at             | datetime     | NO   |     | NULL    |                |
| updated_at             | datetime     | NO   |     | NULL    |                |
+------------------------+--------------+------+-----+---------+----------------+
22 rows in set (0.02 sec)

viewを作る

D:\RailsProjects\portal>rails g devise:views users
      create  app/views/users/_links.erb
      invoke  form_for
      create    app/views/users/confirmations
      create    app/views/users/confirmations/new.html.erb
      create    app/views/users/passwords
      create    app/views/users/passwords/edit.html.erb
      create    app/views/users/passwords/new.html.erb
      create    app/views/users/registrations
      create    app/views/users/registrations/edit.html.erb
      create    app/views/users/registrations/new.html.erb
      create    app/views/users/sessions
      create    app/views/users/sessions/new.html.erb
      create    app/views/users/unlocks
      create    app/views/users/unlocks/new.html.erb
      invoke  erb
      create    app/views/users/mailer
      create    app/views/users/mailer/confirmation_instructions.html.erb
      create    app/views/users/mailer/reset_password_instructions.html.erb
      create    app/views/users/mailer/unlock_instructions.html.erb

以下のルートができていた。

  devise_for :users

以下のように修正する。

  devise_for :users, :controllers => { :sessions => "users/sessions" }

コントローラを作成する。

D:\RailsProjects\portal>rails g controller users/sessions
      create  app/controllers/users/sessions_controller.rb
      invoke  erb
       exist    app/views/users/sessions
      invoke  helper
      create    app/helpers/users/sessions_helper.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/users/sessions.js.coffee
      invoke    scss
      create      app/assets/stylesheets/users/sessions.css.scss

上記コントローラのスーパクラスを以下のように修正する。

class Admins::SessionsController < Devise::SessionsController
end

以下のURLにアクセスすると登録画面が表示される。

http://localhost:3000/users/sign_up