RailsのdeviseというGemを使用してログイン機能等を作る際、
一般の方と企業でログイン画面や管理を分けたいなという時があると思います。
deviseを使用してWebアプリケーションの制作を行ったことはありますが、
今回初めて複数のモデルで実装を行ったため備忘録として残しておきたいと思います。
Ruby: 2.5.6
Rails: 5.2.4
devise: 4.7.3
docker内で作業しますので、bundle exec
がついていますが、
docker外の方は外して入力してみてください。
#devise導入
###1.Gemのインストール
今回はFacebook認証も行いたかったので、devise
とomniauth-twitter
をGemfileへ追加
gem 'devise'
gem 'omniauth-facebook'
そしてbundle install
###2.devise関連のファイル作成
ターミナルで下記コマンドを入力
bundle exec rails g devise:install
以下のような文言が出てくると思います
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 *
===============================================================================
それぞれ内容を確認して追加をしていきます。
1.config/environments/development.rb
に以下の文言を追加してねという内容。
言われた通り、デフォルトのURLを記載します。
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
2.config/routes.rb
にrootでアクセスした時(1で設定したURLにアクセスした時)のURLを設定してねという内容
私はまだ作成していなかったので、ここで作成します。
bundle exec rails g controller Posts(コントローラー名) index
config/routes.rb
にてURLを設定
Rails.application.routes.draw do
root 'posts#index'
end
3.app/views/layouts/application.html.erb
にflashメッセージを追加してねという内容
とりあえず記載されているものを書きました。
.
.
.
<body>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
</body>
</html>
4.viewを生成してねと言われていますが、2パターン作りたいので今は無視します!
#devise設定
ログインユーザーを2パターンにするためにconfig/initializers/devise.rb
の設定を変更していきます。
元々コメントアウトされているので探してください!
.
#config.scoped_views = false
.
.
#config.sign_out_all_scopes = true
.
# 複数のmodelでログイン画面を分けるために変更
config.scoped_views = true
# 複数のmodelでをグインしている際、一方をログアウトした時にもう片方もログアウトしてしまうことを防ぐ
config.sign_out_all_scopes = false
#deviseモデル作成
今回は一般の方と企業の2パターンを作ろうと思います!
bundle exec rails g devise user
bundle exec rails g devise company
###マイグレーションファイルを確認
(モデル名以外同様のファイルが生成されているので、companyモデルのファイルは省略します)
# frozen_string_literal: true
class DeviseCreateUsers < ActiveRecord::Migration[5.2]
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
###modelファイルを確認
Facebook認証を取り入れるため、:omniauthable
とomniauth_providers: [:facebook]
を追記しました。
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :omniauthable, omniauth_providers: [:facebook]
end
変更や追加ができたところでbundle exec rails db:migrate
#ルーディングの確認
###config/routes.rbを確認
Rails.application.routes.draw do
devise_for :companies
devise_for :users
root 'postss#index'
end
###bundle exec rails routesで確認
Controller#Actionの部分がcompanyとuserで同じになってしまっている。
つまり、controllerが同一になってしまっているので変更する必要がある。
(*Controller#Actionだけ離れてしまいました...
めんどくさくて直せていないので、右にスライドしてください・・・!)
Prefix Verb URI Pattern Controller#Action
new_company_session GET /companies/sign_in(.:format) devise/sessions#new
company_session POST /companies/sign_in(.:format) devise/sessions#create
destroy_company_session DELETE /companies/sign_out(.:format) devise/sessions#destroy
new_company_password GET /companies/password/new(.:format) devise/passwords#new
edit_company_password GET /companies/password/edit(.:format) devise/passwords#edit
company_password PATCH /companies/password(.:format) devise/passwords#update
PUT /companies/password(.:format) devise/passwords#update
POST /companies/password(.:format) devise/passwords#create
cancel_company_registration GET /companies/cancel(.:format) devise/registrations#cancel
new_company_registration GET /companies/sign_up(.:format) devise/registrations#new
edit_company_registration GET /companies/edit(.:format) devise/registrations#edit
company_registration PATCH /companies(.:format) devise/registrations#update
PUT /companies(.:format) devise/registrations#update
DELETE /companies(.:format) devise/registrations#destroy
POST /companies(.:format) devise/registrations#create
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_facebook_omniauth_authorize GET|POST /users/auth/facebook(.:format) devise/omniauth_callbacks#passthru
user_facebook_omniauth_callback GET|POST /users/auth/facebook/callback(.:format) devise/omniauth_callbacks#facebook
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
user_password PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
POST /users/password(.:format) devise/passwords#create
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
POST /users(.:format) devise/registrations#create
###ルーディング修正
devise_for :companies, controllers: {
sessions: 'companies/sessions',
passwords: 'companies/passwords',
registrations: 'companies/registrations'
}
devise_for :users, controllers: {
sessions: 'users/sessions',
passwords: 'users/passwords',
registrations: 'users/registrations',
omniauth_callbacks: 'users/omniauth_callbacks'
}
もう一度bundle exec rails routes
で確認していただくと無事controllerの部分が変更されていると思います!
#ビューの作成
最初のrails g devise:install
を実行した際に対応しなかった部分です。
bundle exec rails g devise:views users
bundle exec rails g devise:views companies
それぞれファイルが生成されたかと思います!
#コントローラーの作成
bundle exec rails generate devise:controllers users
bundle exec rails generate devise:controllers companies
こんな感じの実行結果になるかと思います。
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
===============================================================================
下の部分、まさかのエラー!?と思いましたが、エラーじゃないです。(ほっ
controllerがこんな感じだから、追加でroutes.rbに以下のような記述が必要だよ〜
と例を出して教えてくれています。
先ほど設定しているので無視で大丈夫です!
#おまけ(omniauth認証を導入する方)
このままだとhttp://localhost:3000/users/sign_in
にアクセスしてもエラーになると思います。
undefined method `omniauth_authorize_path' for 〜
みたいなやつが。。
Facebook認証の設定についてはここに記載しませんが、
app/views/users/shared/_links.html.erbの
omniauth_authorize_path(resource_name, provider)の部分がおかしいです。
ルーディングを確認するとomniauth_authorize_path
というpathはなく、user_facebook_omniauth_authorize_path
となっているはずなので修正しましょう。
asを使用して名前を変更したわけでもないのになんで・・・?と思いましたが、
理由はよくわからなかったです。最初からなのかな・・・?
#とりあえず完成
何はともあれ!とりあえず基本的な設定部分は完成です。
http://localhost:3000/users/sign_in
とhttp://localhost:3000/companies/sign_in
どちらでアクセスしてもログイン画面が出ると思います!
必要であればカラムを増やしたりカスタマイズしてください!
この記事がどなたかのお役に立てたら嬉しいです。
ありがとうございました!