いつもの
rails new passport -TB --skip-turbolinks
bundlegemを追加しておく
gem "twitter-bootstrap-rails" gem "slim-rails" gem 'devise'
rails generate bootstrap:install static忘れずに
deviseのセットアップ
rails g devise:install
すると以下が表示される
mPro:passport thr3a$ 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', 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. If you are deploying on Heroku with Rails 3.2 only, 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.
5. You can copy Devise views (for customization) to your app by running:
rails g devise:views
===============================================================================
コントローラーの作成
とりあえずサイト全体のindexを作成
rails g controller home index
モデルの作成
rails g devise User
ちなみに以下のマイグレーションが生成される
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, null: false t.datetime :current_sign_in_at t.datetime :last_sign_in_at t.string :current_sign_in_ip t.string :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 :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 end end
モデルも以下
class User < ActiveRecord::Base # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable end
それぞれどんな機能持っているかの確認はここが詳しい。とりあえずデフォルトで
ビューの作成
app/views/home/index.html.slimを以下に変更
- if user_signed_in?
p = current_user.email
=link_to "Settings", edit_user_registration_path
=link_to "Logout", destroy_user_session_path, method: :delete
- else
=link_to "Sign up", new_user_registration_path
=link_to "Login", new_user_session_path
大元のerbもapp/views/layouts/application.html.slimに変更してメッセージを追加
doctype html
html
head
title My App
meta name="viewport" content="width=device-width, initial-scale=1.0"
= stylesheet_link_tag "application", media: 'all'
= javascript_include_tag "application"
= csrf_meta_tags
body
- if notice
p.alert.alert-success = notice
- if alert
p.alert.alert-danger = alert
= yield
ルーティングの設定
config/route.rbを以下に変更 deviseはリダイレクトにroot_path使ってるので指定しないと死ぬ
devise_for :users get 'home/index' root 'home#index'
以上でユーザー登録機能までの一通りが実装される。スゲェ簡単
試しに登録してみるとこんな感じでDBに入る
=> #<ActiveRecord::Relation [#<User id: 1, email: "a@a.com", encrypted_password: "$2a$10$DuA68xuU25/C8/cS5.7bVekwr/DV3N.4/DLutd3gndR...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 2, current_sign_in_at: "2015-11-06 05:46:14", last_sign_in_at: "2015-11-06 05:33:05", current_sign_in_ip: "::1", last_sign_in_ip: "::1", created_at: "2015-11-06 05:33:05", updated_at: "2015-11-06 05:46:40">]>
パスワードリセットのメールが送信できない
ふぇえ
Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
ちゃんと説明読もうな
config/environments/development.rbに以下を例に設定してあげる。以下はActionmailerを利用したGmail経由の設定
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.delivery_method = :smtp
#config.action_mailer.raise_delivery_errors = true
config.action_mailer.smtp_settings = {
:enable_starttls_auto => true,
:address => 'smtp.gmail.com',
:port => '587',
:domain => 'smtp.gmail.com',
:authentication => 'plain',
:user_name => '<Gmailアカウント>@gmail.com',
:password => '<Gmailパスワード>'
}
ただしGoogleアカウント側にも設定が必要なので注意
日本語化
https://raw.githubusercontent.com/tigrish/devise-i18n/master/rails/locales/ja.ymlを適当にdevise.ja.ymlをconfig/localesにブチ込む
あとja.ymlに以下を追記
ja:
activerecord:
attributes:
user:
name: 名前
password: パスワード
password_confirmation: パスワード確認
email: メールアドレス
無心で実行
rails g devise:views
deviseはerb以外のビューに対応していない。そこでerb2slimを用いて変換する
erb2slim -d app/views/devise/
ちなみに以下のようなビューが生成されるらしい)
- app/views/devise/shared/_links.html.erb (リンク用パーシャル)
- app/views/devise/confirmations/new.html.erb (認証メールの再送信画面)
- app/views/devise/passwords/edit.html.erb (パスワード変更画面)
- app/views/devise/passwords/new.html.erb (パスワードを忘れた際、メールを送る画面)
- app/views/devise/registrations/edit.html.erb (ユーザー情報変更画面)
- app/views/devise/registrations/new.html.erb (ユーザー登録画面)
- app/views/devise/sessions/new.html.erb (ログイン画面)
- app/views/devise/unlocks/new.html.erb (ロック解除メール再送信画面)
- app/views/devise/mailer/confirmation_instructions.html.erb (メール用アカウント認証文)
- app/views/devise/mailer/reset_password_instructions.html.erb (メール用パスワードリセット文)
- app/views/devise/mailer/unlock_instructions.html.erb (メール用ロック解除文)
メールアドレスだけじゃなくて名前も登録したい
登録項目を増やすにはまず普通にマイグレーションを追加
rails g migration AddNameToUsers name
マイグレーションにてnameカラムオプションにnull: false, default: ""を追加
class AddNameToUsers < ActiveRecord::Migration
def change
add_column :users, :name, :string, null: false, default: ""
end
end
必須項目にするならモデルにバリデーションを追加しておく
validates :name, presence: true, length: { maximum: 10 }
rake db:migrate:resetしたのちにビューに追加 以下は例
.field
= f.label :name
= f.text_field :name, autofocus: true
残念ながらこれだけでは終わらない。Railsたん最強罠であるStrong Parametersがnameパラメータを阻むからである。
そこで公式READMEを参考に以下を追加
class ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? protected def configure_permitted_parameters devise_parameter_sanitizer.for(:sign_up) << :name devise_parameter_sanitizer.for(:sign_in) << :name devise_parameter_sanitizer.for(:account_update) << :name end end
indexページ等特定のページでは認証を必要としない
app/controllers/application_controller.rbにて
before_action :authenticate_user!, except: [:show, :index]
/users/sign_inを/users/loginに変更したい
ルーティングの変更はroutes.rbで行うことができる
デフォルトのルーティング
mPro:passport thr3a$ rake routes
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
home_index GET /home/index(.:format) home#index
root GET / home#index
例えば
/users/sign_inから/users/loginusers/sign_outから/users/logout
に変更したい場合は以下のようにする
devise_for :users, path_names: { sign_in: "login", sign_out: "logout"}
プロフィール画面欲しい
deviseは一発でそれっぽく生成してくれるがindexとshow(に相当するページ)は作らない。のでそこは自分でこしらえる。
コントローラー生成
rails g controller users index show
適当に作る
class UsersController < ApplicationController def index @users = User.all end def show @user = User.find(params[:id]) end end
ルーティングの設定 devise_forの後に書かないと死ぬ
Rails.application.routes.draw do
devise_for :users, path_names: { sign_in: "login", sign_out: "logout"}
root 'home#index'
→resources :users, :only => [:index, :show]
index.html.slim
ul
- @users.each do |user|
li = user.email
show.html.slim
h1 = @user.name p = @user.email
これでおk
編集後のリダイレクトを変えたい
編集後、デフォルトだとTOPページ(root_path)に飛ぶけどそのまま編集ページに戻りたい場合だってあると思うの
どうもオーバーライドすることで実現できる。 app/controllers/users/registrations_controller.rbを新規作成して以下
class RegistrationsController < Devise::RegistrationsController protected def after_update_path_for(resource) edit_user_registration_path end end
あとはroutes.rbに以下を追記するだけ
devise_for :users, :controllers => {
:registrations => "registrations"
}
こことか多くのサイトがusers/registrationsしてたんだけど何が違うんだろう(無理だった