Rails + Devise で認証機能を作成(カスタマイズあり)

やりたいこと
・認証機能がほしい
・deviseデフォルトのメールアドレスではなく、ユーザー名での認証がしたい
 ※パスワードを忘れた場合のメール送信とかはいらない
・管理者ユーザーと一般ユーザーを使い分けたい

バージョン
ruby 1.9.3p194
rails 3.2.8
devise 1.5.5

はじめに
■deviseをインストール&初期セット

$ vi Gemfile

gem 'devise', '1.5.5'

$ bundle install
$ rails g devise:install
$ rails g devise User
$ rails g devise:views
$ rake db:migrate
$ mv public/index.html public/index.html.org

ユーザー名で認証を行う
■メールアドレス→ユーザー名での認証に変更

$ rails g migration add_username_to_users username:string
$ rake db:migrate
$ vi app/models/user.rb

# :username を追加
attr_accessible :email, :password, :password_confirmation, :remember_me, :username
 
# email_required? メソッドを追加
def email_required?
 false
end

$ vi app/views/devise/sessions/new.html.erb
$ vi app/views/devise/registrations/edit.html.erb
$ vi app/views/devise/registrations/new.html.erb
※全て同じ修正

<div><%= f.label :email %><br />
<%= f.email_field :email %></div>

↓下記のとおり修正

<div><%= f.label :username %><br />
<%= f.text_field :username %></div>

■Userテーブルをマイグレート
$ rails g migration change_column_email_to_null_false

def self.up
 change_column :users, :email, :string, :null => false
end
 
def self.down
 change_column :users, :email, :string, :null => true
end

$ rails g migration change_index_from_email_to_username_on_users

def self.up
 remove_index :users, :email
 add_index :users, :username
end
 
def self.down
 add_index :users, :email
 remove_index :users, :username
end

■ config/initializers/devise.rb を修正
修正前(コメントアウトされている)

# config.authentication_keys = [ :email }

修正後(コメントイン & username に修正)

config.authentication_keys = [ :username }

管理者権限の追加

■Userテーブルをマイグレート(admin:booleanを追加)
$ rails g migration add_admin_to_users admin:boolean
$ rake db:migrate

■Usersコントローラーを作成
$ rails g controller users
$ vi config/routes.rb

 # devise_for :users を修正
 devise_for :user

■UsersコントローラーにCRUDメソッドを一通りそろえる。

■Usersコントローラーに管理者権限追加、削除メソッドを追加

def make_admin
 user = User.find(params[:id])
 user.update_attribute :admin, true
 redirect_to users_path
end

def remove_admin
  user = User.find(params[:id])
 user.update_attribute :admin, false
 redirect_to users_path
end

その他

■Welcomeコントローラーを作成
※サインインページにリダイレクトさせるコントローラー
$ rails g controller welcome
$ vi app/welcome_controller.rb

class WelcomeController < ApplicationController
 def index
  redirect_to new_user_session_path
 end
end

■config/routes.rb に追記

 # 認証後のトップページを指定
 # welcomeコントローラーを作成してサインインページにリダイレクトさせる
 root :to => 'welcome#index'
 resources :welcome, :only => [ 'index' ]
 get 'portal', :to => 'portal#index', :as => :user_root  # 'portal'はログイン後に表示させたいリソース名