deviseを使ったユーザー管理機能(ログイン・ログアウト)の実装手順
今回はトップページの作成も合わせて行います。
トップページを既に作成済みの方は、ログイン機能の実装のみお読みください。
###作業の流れ
####・トップページの作成
- homesコントローラ作成
- homesコントローラの編集
- トップページのビュー作成
- ルーティングの編集
####・ログイン機能の実装
- gem 'devise' のインストール
- deviseの設定ファイル作成
- ログイン機能付きUserモデルの作成
- データベースに反映
トップページの作成
早速作業に入りましょう
1. homesコントローラの作成
今回は例として homesコントローラ
を作成します。
$ rails g controller homes
*コマンドを実行すると以下のようなものが作成されます。
Running via Spring preloader in process ****
create app/controllers/homes_controller.rb
invoke erb
create app/views/homes
invoke test_unit
create test/controllers/homes_controller_test.rb
invoke helper
create app/helpers/homes_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/homes.coffee
invoke scss
create app/assets/stylesheets/homes.scss
2. homesコントローラの編集
続いて先ほど作成された、homes_controller.rb
に indexアクション
を定義します。
class HomesController < ApplicationController
def index
end
end
3. トップページのビュー作成
次に homesコントローラ
のindexアクション
が呼ばれた際に返すビューを用意します。
app/views内のhomesディレクトリにindex.html.erb
を新規作成してください。
後でちゃんとこのページが呼ばれているか確認するため、index.html.erb
にテキストを入力しておきます。
4. ルーティングの編集
トップページを表示するためのルーティングを設定します。
Rails.application.routes.draw do
root to: "homes#index"
end
これで トップページの作成 は完了です。
最後にローカルサーバを起動して、ちゃんと表示されるか確認しておきましょう。
rails s
を実行してからこちらをクリック➡️ http://localhost:3000/
白くて分かりづらいですが、以下のような画面が表示されればOKです。
ログイン機能の実装
それでは ログイン機能の実装 に入ります。
1. gem 'devise' のインストール
まずは今回ログイン機能の実装に使用する'devise'
というgemをインストールします。
Gemfileの最後の行にgem 'devise'
を追記してください。
====== 省略 ======
gem 'devise'
続けてターミナルでgemのインストールを実行します。
$ bundle install
補足)gem list
コマンドを実行し、きちんとgemがインストールされているか確認しておきましょう。
$ gem list
*** LOCAL GEMS ***
==== 省略 ====
debug_inspector (0.0.3)
devise (4.7.1) ⬅️deviseがインストールされていればOK
did_you_mean (1.2.0)
diff-lcs (1.3)
domain_name (0.5.20190701)
==== 省略 ====
2. deviseの設定ファイル作成
次にdeviseを使用する際に必要な設定ファイルを作成します。
deviseに関するファイルなのでdevise専用コマンドを使用します。
$ rails g devise:install
Running via Spring preloader in process ****
create config/initializers/devise.rb
create config/locales/devise.en.yml
3. ログイン機能付きUserモデルの作成
ユーザー情報を登録するためのモデル、マイグレーションファイルなどを作成します。
ここでもdevise専用コマンドを使用します。
$ rails g devise user
Running via Spring preloader in process ****
invoke active_record
create db/migrate/20200404053603_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
※注意:userの前にmodelをつけるとmodelモデルが作成されてしまいます。
上記コマンドを実行すると、自動的に以下のようなルーティングが生成されます。
Rails.application.routes.draw do
devise_for :users ⬅️自動で生成
root to: "homes#index"
end
4. データベースに反映
最後にユーザーの情報を登録できるようにするため、マイグレーションファイルをデータベースに反映します。
$ rails db:migrate
== 20200404053603 DeviseCreateUsers: migrating ================================
-- create_table(:users)
-> 0.0122s
-- add_index(:users, :email, {:unique=>true})
-> 0.0113s
-- add_index(:users, :reset_password_token, {:unique=>true})
-> 0.0128s
== 20200404053603 DeviseCreateUsers: migrated (0.0366s) =======================
以上でログイン機能の実装は完了です。
早速確認してみましょう。
ローカルサーバを起動し、URLの末尾にusers/sign_up
と入力して、新規登録画面を確認しましょう。以下のような画面が表示されます。
続いて、URLの末尾をusers/sign_in
に変更するか、sign_up画面のlog inのリンクをクリックして、ログイン画面を確認しましょう。
画面が確認できればOKです。お疲れ様でした。
また、ここまでお読み頂きありがとうございました。
追加補足
補足1) 4. データベースに反映 を忘れていた場合、以下のようなPendingMigrationErrorというエラーが発生してしまいます。要は、データベースに反映されていないマイグレーションファイルが残ってるよ。という意味です。
補足2)もし rails db:migrate を実行したはずなのに上記のエラー画面が表示される場合は、rails db:migarate:status
コマンドを実行してマイグレーションの状況を確認しましょう。
$ rails db:migrate:status
database: sample_app_development
Status Migration ID Migration Name
--------------------------------------------------
down 20200404053603 Devise create users
補足3)上記のように Status がdown
の場合はきちんとマイグレーションファイルの反映が行われていません。再度db:migrate
を実行してください。Status が UP
になればOKです。
補足4)上記のエラーとは別に、もし以下のようなNoMethodErrorというエラーが発生した場合は、ローカルサーバを再起動しましょう。
追加実装
ログイン画面へのリンクをつくるのが面倒なので、ログインしていないとトップページにいけないようにしてしまいましょう。追記するのは以下の一点です。
class ApplicationController < ActionController::Base
before_action :authenticate_user! ⬅️この一行を追記
end
補足)このままではログアウトができないので、ログアウトのリンクだけ作成しておきます。
index.html.erb
を以下のように編集しましょう。
これは"homes#index"ページです。
<br>
ログアウトしますか?
<%= link_to "はい", destroy_user_session_path, method: :delete %>