38
56

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Ruby on Rails】 devise 新規登録 ログイン 実装 手順

Last updated at Posted at 2019-04-22

はじめに

WEBサイトを作成する上で、ユーザーの登録からログイン・ログアウトまでできるサイトがほとんどだと思います。今回は、deviseを使って実装していきましょう。

目次

  • サーバーが起動していたら停止する
  • Gem(devise)をインストールする
  • deviseの設定ファイルを作成する
  • Userモデルを作成する
  • 必要なビューの知識
  • パスの調べ方(prefix)
  • サインイン(user_signed_in?)
  • リダイレクトをコントローラーに実装する
  • 新規登録・ログイン画面を実装する(view)
  • usersテーブルに名前を保存できるようにする
  • 命名規則(スネークケース・キャメルケース)
  • 新規登録画面に名前フォームを追加する
  • ストロングパラメータを編集する(devise用)

サーバーが起動していたら停止する

control + Cキー を同時押ししましょう。

Gem(devise)をインストールする

まずはじめにGemfileに以下を追記しましょう。

Gemfile
gem 'devise'

続いて bundle install を実行します。

ターミナル
$ bundle install

deviseの設定ファイルを作成する

ターミナル
$ rails g devise:install

deviseに必要な2つのファイルが生成されました。

ターミナル
create  config/initializers/devise.rb
create  config/locales/devise.en.yml

ユーザーを登録するためには、何が必要でしょうか?そうですアカウントを保存するためのデータベースが必要ですね。まずは、モデルを作っていきましょう。

Userモデルを作成する

ここで注意しなければいけないのがdevise専用のコマンドを実行することです。
以下を実行してUserモデルを生成します。

ターミナル
$ rails g devise user

必要なファイルが生成されました。
モデルを生成しただけでは、テーブルは作成されていませんね。
以下のコマンドを実行してテーブルを作成しましょう。

$ rake db:migrate

これでテーブルができました。

必要なビューの知識

ここで、少しビューの知識についても触れておきます。なぜならログイン機能は、ログインされている時とログアウトしている時のナビゲーションの表示が異なる場合がほとんどだからです。

表示タグ(<% %>)

<% post.text %>

ビューに表示されない

<%= post.text %>

ビューに表示される

リンク(link_to)

HTMLだとaタグと同様だと思ってください。html.erbファイルでは、以下のように記述します。

<%= link_to 'ビューに表示される文字', 'パス' %>

クラスをつける場合は以下のようになります。

<%= link_to 'ビューに表示される文字', 'パス', class: 'クラス名' %>

パスの調べ方(prefix)

Railsでは、パスをターミナルで調べる方法があります。

ターミナル
$ rake routes

実行後

ターミナル
posts_new GET    /posts/new(.:format)   posts#new

現在、使えるパスがズラーッと表示されたかと思いますが、

ターミナル
posts_new

これが、リンクタグなどで使えるパスになります。ただ、これを追記するだけではエラーになってしまいます。例えば、新規投稿画面へのリンクをブラウザに表示する場合には以下を参考にしてください。

html.erb
<%= link_to '新規投稿画面へ移動します', 'posts_new_path' %>

このように調べたパスのあとに _path とつけるだけです。

サインイン(user_signed_in?)

ログイン・ログアウト機能で必要なメソッドになります。使い方は簡単です。

html.erb
<% if user_signed_in? %>
    # ユーザーがサインインしている場合に実行する処理
<% end %>

サインアウトしている場合は、なにを追記すればいいでしょうか?ヒントは条件分岐です。

html.erb
<% if user_signed_in? %>
    # ユーザーがログインしている場合に実行する処理
<% else %>
  # ユーザーがログアウトしている場合に実行する処理
<% end %>

ログイン・ログアウトの機能は全てのページに表示させておく必要があるので、共通のビューに関する記述は app/views/layouts/application.html.erb でしたね。

application.html.erb
<header class="header">
      <div class="header__bar row">
        <h1 class="grid-6"><a href="/">サイトタイトル</a></h1>

        <% if user_signed_in? %>
          <div class="user_nav grid-6">
            <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
            <a class="post" href="/posts/new">投稿する</a>
          </div>

        <% else %>
          <div class="grid-6">
            <%= link_to "ログイン", new_user_session_path, class: 'post' %>
            <%= link_to "新規登録", new_user_registration_path, class: 'post' %>
          </div>

        <% end %>
      </div>
</header>

上記は、あくまで参考ですので、レイアウトは変更してください。これで、ナビゲーションにログイン・ログアウトのリンクをつけることができました。

リダイレクトをコントローラーに実装する

ログイン・ログアウト機能まで実装することができました。ただ、一つ問題点があります。それは、新規投稿のパスに直接アクセスできてしまいます。それができないようにログインしてない場合には強制的にログイン画面に移動するようにリダイレクトという機能を実装していきます。

リダイレクトする(redirect_to)

Railsでは、アクション内の処理が終了すると"自動的"にアクション名と同名のビューが表示されますので、アクションの処理が終わり強制的に別のアクションを実行する場合などに使います。

redirect_to action: :index
               キー: :バリュー

※indexアクションにリダイレクトするという記述になります。

指定のアクションを優先して実行する(before_action)

pusts_controller.rb
    before_action :manji, except: :index
    # indexアクション以外が実行される前にmanjiメソッドが実行される。

    def index
      @posts = Post.all
    end

    private
    def manji
    end

それでは、ログインしていないときに新規投稿しようとすると、indexアクションに強制リダイレクトするようにmanjiアクションに記述していきます。

pusts_controller.rb
private
def manji
  redirect_to action: :index unless user_signed_in?
end

unlessという見慣れないコードがでてきました。

unless文

簡単にいうとif文と真逆の処理をします。
if文は もしも評価が真(true)であれば○○する でしたね。
unless文は もしも評価が偽(false)であれば○○する という意味になります。

unless 条件式
    # 条件式が偽(false)のときに実行する処理
else
    # 条件式が真(true)のときに実行する処理
end

それでは、コントローラーを以下に編集します。

pusts_controller.rb
class PostsController < ApplicationController

    before_action :manji, except: :index

    def index
      @posts = Post.page(params[:page]).per(5).order("created_at DESC")
    end

    def new
    end

    def create
      post.create(post_params)
    end

    private
    def post_params
      params.permit(:name, :text)
    end

    def manji
      redirect_to action: :index unless user_signed_in?
    end
  end

これで、ログイン前に新規投稿ができるという問題が解決しました。

ログイン・新規登録画面を実装する(view)

deviseでログイン機能を実装すると、ログイン・新規登録画面は自動的に生成されますがビューファイルとしては生成されていません。ブラウザで、新規登録・ログインに進むと表示されますがこれはGem(devise)中のビューを読みこんでいるためです。
そこで、ログイン・新規登録画面のビューを変更するには以下のコマンドで、devise用のviewファイルを生成する必要があります。

ターミナル
$ rails g devise:views

実行すると app/views/devise にファイルが生成されました。

新規登録画面のviewを変更する

registrationsとは英語という意味になります。翻訳するとなんとなくパスも理解できると思います。

app/views/devise/registrations/new.html.erb
<div class="contents row">
    <h2>Sign up</h2>
    <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
      <%= devise_error_messages! %>

      <div class="field">
        <%= f.label :email %><br />
        <%= f.email_field :email %>
      </div>


      <div class="field">
        <%= f.label :password %>
        <% if @validatable %>
        <em>(<%= @minimum_password_length %> characters minimum)</em>
        <% end %><br />
        <%= f.password_field :password, autocomplete: "off" %>
      </div>

      <div class="field">
        <%= f.label :password_confirmation %><br />
        <%= f.password_field :password_confirmation, autocomplete: "off" %>
      </div>

      <div class="actions">
        <%= f.submit "Sign up" %>
      </div>
    <% end %>
  </div>

ログイン画面のviewを変更する

app/views/devise/sessions/new.html.erb
<div class="contents row">
    <h2>Log in</h2>

    <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>

      <div class="field">
        <%= f.label :email %><br />
        <%= f.email_field :email, autofocus: true %>
      </div>

      <div class="field">
        <%= f.label :password %><br />
        <%= f.password_field :password, autocomplete: "off" %>
      </div>

      <% if devise_mapping.rememberable? -%>
        <div class="field">
          <%= f.label :remember_me %><br />
          <%= f.check_box :remember_me %>
        </div>
      <% end -%>

      <div class="actions">
        <%= f.submit "Log in" %>
      </div>
    <% end %>
  </div>

CSSやbootstrapのレイアウトについては、割愛しております。

ブラウザでログイン・新規登録画面を確認する

これで、ユーザー登録・ログインの準備ができました。今回は、登録するユーザーの名前も保存するようにします。ではここで、データの保存先(usersテーブル)確認してみます。
usersテーブルには「idカラム」「emailカラム」「passwordカラム」しか存在していないので、名前にあたる「nameカラム」を追加していきましょう。

usersテーブルに名前を保存できるようにカラムを追加する

名前を追加するためにusersテーブルにnameカラムを追加していきましょう。ここには、新規登録の時に登録する名前を保存できるようにします。

マイグレーションファイルを作成してカラムを追加する

ファイルを生成するコマンドは "rails g" でしたね。

ターミナル
$ rails g migration AddNameToUsers name:string

解説

ターミナル
$ rails g migration AddカラムToテーブル カラム:データの型

以下のコマンドを実行してテーブルを生成します。

ターミナル
$ rake db:migrate

これで、usersテーブルにnameカラムを追加することができました。
もし間違ったカラム名で追加してしまった場合などは一つ前に戻るコマンドを実行しましょう。

ターミナル
$ rake db:rollback

を実行したあとできてしまったマイグレーションファイルを消しましょう。

migrationファイルがどのような状態なのか確認するコマンド

$ rake db:migrate:status
Status   Migration ID    Migration Name
--------------------------------------------------
   up     20190420082207  Create tweets
   down   20190421185018  Devise create users

upなら実行されていてdownは未実行という意味

マイグレーションカラムの追加(add_column)

まず、マイグレーションファイルの生成をします。

ターミナル
$ rails g migration AddRateToテーブル名

マイグレーションファイルに追記します。

マイグレーションファイル例
class AddPriceToBooks < ActiveRecord::Migration[5.2]
  def change
    add_column :テーブル, :カラム, :型
    add_column :テーブル, :カラム, :型
  end
end

マイグレーションカラムの削除(remove_column)

マイグレーションファイル
remove_column :テーブル名, :カラム名, :カラムの型

命名規則

先程、マイグレーションファイルを生成する時にターミナルに記述した命名規則2つを紹介します。

キャメルケース

単語の頭文字を大文字で繋げる

AddNameToUsers name:string

スネークケース

_で区切る

add_name_to_users name:string

新規登録画面に名前フォームを追加する

app/views/devise/sessions/new.html.erb
<div class="contents row">
    <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 :name %> <em>(6 characters maximum)</em><br />
        <%= f.text_field :name, autofocus: true, maxlength: "8" %>
      </div>
      <!-- ここまでを追記します -->

      <div class="field">
        <%= f.label :email %><br />
        <%= f.email_field :email %>
      </div>

      <div class="field">
        <%= f.label :password %>
        <% if @validatable %>
        <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" %>
</div>

登録フォームに名前を登録するフォームが表示できました。

ストロングパラメータを編集する(devise用)

新規登録時に入力された情報はパラメーターとしてサーバーに送信されます。
ただ、deviseにはコントローラーが存在しないためapplication_controller.rbにdevise

38
56
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
56

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?