1
Help us understand the problem. What are the problem?

posted at

🔰【初学者用】deviseを使ってユーザー管理機能を実装しよう!【Ruby on Rails】

はじめに

プログラミング初学者の私がアウトプットとこれから学習される皆様の参考になればと思い投稿しています。
まだ、マークダウン記法も不慣れな初学者ですので、間違い等があれば指摘いただけると幸いです。

この記事を見てできるようになること

Ruby on Railsのgemであるdeviseを使用して、ユーザー管理機能を実装できるようになります!

deviseとは?

ユーザー管理機能(例:ログイン、ログアウト、新規登録)を簡単に実装するためのGemです。

deviseの導入

まずGemfileを編集します。追記する場所はGemfileの最後の行で構いません。

Gemfile
gem 'devise'

⚠注意
deviceとしないこと!
私はこれでかなりの時間を消費しました:cry:

使用するアプリディレクトリを開き以下のコマンドでgemをインストールします。

ターミナル
bundle install

次にローカルサーバーを起動or再起動させます。
サーバーを起動していなかった場合↓(起動)

ターミナル
rails s

元々サーバーを起動していた場合↓(再起動)

ターミナル
control + C
rails s  

これでdeviseの導入は完了です!

deviseの設定ファイルを作成

以下のコマンドを実行してください。

ターミナル
rails g devise:install

上記コマンドを実行することで、deviseに関する設定ファイルを自動生成してくれます。
これでdeviseの設定ファイルの作成は完了です!

deviseのuserモデルを作成

続いてUserモデルを作成していきますがここで注意点があります。

deviseを使用する場合、通常のモデル作成方法とは異なります。

通常モデルを作成する場合はrails g model userのように実行しますが、deviseを利用する場合は以下のように記述し実行します。以下のコマンドを実行してください。

ターミナル
rails g devise user

上記コマンドを実行することでrails g deviseコマンドという、モデルとマイグレーションの作成やルーティング設定をまとめてしてくれます。
モデルとマイグレーションの作成やルーティング設定↓

config/routes.rb
Rails.application.routes.draw do
  devise_for :users #追加された記述
  root to: 'tweets#index'
  resources :tweets
end
db/migrate/20XXXXXXXXX_devise_create_users.rb
class DeviseCreateUsers < ActiveRecord::Migration[6.0]
 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

     # 省略

     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

デフォルトでカラムが設定されていますが、新たにカラムが必要であれば自身で記述します。
新しいカラムを追加した場合、マイグレーションを忘れずに実行してください。

ターミナル
% rails db:migrate

ちなみにrails g migration Addカラム名To追加先テーブル名 追加するカラム名:型とすることで、テーブルにカラムを追加する際に必要なコードが記述された状態で、マイグレーションが生成されます。

サンプルコード
ターミナル
% rails g migration AddNicknameToUsers name:string

※上記は一例です。必ず実行しなければならないわけではありません。

deviseのビューを作成

続いてビューファイルを作成していきます。
以下のコマンドを実行してください。

ターミナル
% rails g devise:views

上記コマンドでdevise用のビューファイルが生成されました
サインアップ画面:app/views/devise/registrations/new.html.erb
ログイン画面:app/views/devise/sessions/new.html.erb
作成されていることが確認できたら自分好みに編集しましょう!

deviseのコントローラー

deviseのコントローラーは直接編集できません。 理由はdeviseのコントローラーがGemに記載されているからです。
そのため、編集ができるapplication_controller.rbにストロングパラメーターを定義し、その処理を読み込ませます。
一例としてはこのような記述↓

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  private
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
  end
end

まずは2行目から説明します。

app/controllers/application_controller.rb
before_action :configure_permitted_parameters, if: :devise_controller?

before_actionの記述で各コントローラーよりも先に指定のアクションを行ってくれます。
:configure_permitted_parametersの記述はメソッド名です。慣習的にこのメソッド名で定義することが多いため使用しています。
if: :devise_controller?の記述でdeviseのコントローラに対してのみメソッドの処理を行うようにします。なお、:devise_controller?はdeviseのヘルパーメソッドです。

次に5行目〜7行目を説明します。

app/controllers/application_controller.rb
def configure_permitted_parameters
  devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
end

devise_parameter_sanitizerはdeviseにおけるparamsのようなメソッドです。「ログイン」「新規登録」などのリクエストからパラメーターを取得できます。
以下のように記述します。

devise_parameter_sanitizer.permit(:deviseの処理名, keys: [:許可するキー])

devise処理名の一例

処理名 役割
:sign_in ログイン処理
:sign_up 新規登録処理
:account_update アカウント情報更新の処理

記述を終えたら実際にユーザーを登録してみましょう!

ログインの有無で表示を変える

ログインの有無で表示を変えるにはuser_signed_in?メソッドを使用します。このメソッドはログインしていればtrue、ログインしていなければfalseを返します。
使用例↓

views/layouts/application.html.erb
<% if user_signed_in? %>
  <div class="">
    <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
    <%= link_to "投稿する", new_tweet_path, class: "post" %>
  </div>
<% else %>
  <div class="">
    <%= link_to "ログイン", new_user_session_path, class: "post" %>
    <%= link_to "新規登録", new_user_registration_path, class: "post" %>
  </div>
<% end %>

この記述の場合、ログインしていればログアウト・投稿する、ログインしていなければログイン・新規登録を表示します。

ログインしてないユーザーをリダイレクトする

ログインしていないユーザーをリダイレクトするには以下のような記述を行います。

app/controllers/tweets_controller.rb
class TweetsController < ApplicationController
  before_action :move_to_index, except: [:index, :show]
〜中略〜
  private
  def move_to_index
    unless user_signed_in?
      redirect_to action: :index
    end
  end
end

まず2行目のexcept: [:index, :show]です。expectはbefore_actionで使用できるオプションで、除外するという意味があり、指定したアクションに対しては事前の処理が実行されなくなります。この場合だと、indexとshowアクションが除外の対象になります。
続いて6行目のunless user_signed_in?です。unlessは条件式がfalseの時に処理が実行されます。この記述の場合user_signed_in?を使用しているので、ユーザーがログインしていない場合処理を行うということになります。
最後に7行目redirect_to action: :indexです。で以下のように記述します。

redirect_to action: :リダイレクト先となるアクション名

この記述によりリダイレクト先のを指定できます。

上記記述をまとめるとログインしていないユーザーはindexアクションにリダイレクトされるが、indexアクションとshowアクションはmove_to_indexの対象外である。

ということになります。

まとめ

以上がdeviseを用いたユーザー管理機能の実装方法でした。
これだけで簡単な流れは抑えられたはず!

※プログラミング初学者が投稿しております。訂正等がありましたら、コメントよろしくお願いします。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
1
Help us understand the problem. What are the problem?