はじめに
Railsアプリケーションでログイン機構を実装する上で便利なgem"devise"の使い方を備忘録を兼ねてまとめました。
(0.準備)
以下のdeviseの説明以前に新しいRailsプロジェクトを立ち上げサインインに使うトップページのインデックスアクションを用意しておきました。
$ rails new sample_app
$ rails g controller home index
Running via Spring preloader in process 4619
create app/controllers/home_controller.rb
route get 'home/index'
invoke erb
create app/views/home
create app/views/home/index.html.erb
invoke test_unit
create test/controllers/home_controller_test.rb
invoke helper
create app/helpers/home_helper.rb
invoke test_unit
invoke assets
invoke scss
create app/assets/stylesheets/home.scss
1.deviseのインストール
deviseをインストールします。
gemfileに追記し、ターミナルで bundle install してdeviseをインストールする。
(bundle install:Gemfile.lockとの差分をインストール
bundle update:Gemfile.lockの内容に関わらずGemfileをイチからインストール。)
gem 'devise' # gemfileの一番下に記述
2.deviseの設定ファイルの生成
$ rails g devise:install
設定ファイルのまとまったconfigディレクトリ配下にdeviseの設定ファイルが2つ生成されていることが確認できます。
(実行結果)
Running via Spring preloader in process 3816
create config/initializers/devise.rb
create config/locales/devise.en.yml
===============================================================================
Depending on your application's configuration some manual setup may be required:
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.
* Required for all applications. *
2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:
root to: "home#index"
* Not required for API-only Applications *
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>
* Not required for API-only Applications *
4. You can copy Devise views (for customization) to your app by running:
rails g devise:views
* Not required *
===============================================================================
3.Userコントローラーの生成
$ rails g devise:controllers users
devise専用コマンドでUserコントローラーを生成します。
app/controllers/users配下に6つのファイルが生成されたことが確認できます。
(実行結果)
create app/controllers/users/confirmations_controller.rb
create app/controllers/users/passwords_controller.rb
create app/controllers/users/registrations_controller.rb
create app/controllers/users/sessions_controller.rb
create app/controllers/users/unlocks_controller.rb
create app/controllers/users/omniauth_callbacks_controller.rb
===============================================================================
Some setup you must do manually if you haven't yet:
Ensure you have overridden routes for generated controllers in your routes.rb.
For example:
Rails.application.routes.draw do
devise_for :users, controllers: {
sessions: 'users/sessions'
}
end
===============================================================================
4.Userモデルの生成
$ rails g devise User
devise専用コマンドでUserモデルを生成します。
(実行結果)
Running via Spring preloader in process 4065
invoke active_record
create db/migrate/20210830043528_devise_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
insert app/models/user.rb
route devise_for :users
$ rails db:migrate
忘れずにdb:migrateしてマイグレーションファイルをDBに反映させましょう。
5.viewファイルの生成
kanji@MacBook-Pro % rails g devise:views
Running via Spring preloader in process 4355
invoke Devise::Generators::SharedViewsGenerator
create app/views/devise/shared
create app/views/devise/shared/_error_messages.html.erb
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
多くのファイルが自動生成されましたが特に重要なファイルが以下の2つ。
ユーザー登録画面:app/views/devise/registrations/new.html.erb
ログイン画面:app/views/devise/sessions/new.html.erb
6.フォームの生成
生成したUserモデルをもとに、トップページのビューに新規登録フォームを作ります。
<h1>App Name</h1>
<% if user_signed_in? %>
<h4> メールアドレス: <%= current_user.email %> </h4>
<%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
<% else %>
<h2> 現在ログインしていません </h2>
<%= link_to "ログイン", new_user_session_path, class: 'post' %>
<%= link_to "新規登録", new_user_registration_path, class: 'post' %>
<% end %>
終わりに(nameカラムを加えるには)
ここまでででrails serverを立ち上げ"http://localhost:3000/home/index" へアクセスすると作成されたフォームが確認できます。
Railsチュートリアルと比較すると現在ではUserモデルにnameカラムがないので追加する場合は以下の手順で。
・usersテーブルにnameカラムを追加
ターミナル
$ rails g migration add_name_to_users name:string
$ rails db:migrate
app/views/devise/registrations/new.html.erb
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<!-- ここから追加してください -->
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<!-- ここまで追加してください -->
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "new-password" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
login_app/app/controllers/application_controller
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
# ここから追加します
before_action :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
end
# ここまで追加します
end
app/views/devise/registrations/new.html.erb
<h1>App Name</h1>
<% if user_signed_in? %>
<h2> 現在 <%= current_user.name %> さんがログインしています </h2>
<h4> メールアドレス: <%= current_user.email %> </h4>
<%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
<% else %>
<h2> 現在ログインしていません </h2>
<%= link_to "ログイン", new_user_session_path, class: 'post' %>
<%= link_to "新規登録", new_user_registration_path, class: 'post' %>
<% end %>
少しでもどなたかの参考になれば幸いです。
Twitterで日々の学習をアウトプットしています。
未熟者ですが、ご興味あれば覗いてやってください。→Twitter