読者です 読者をやめる 読者になる 読者になる

ちーくんのブログ

プログラミング備忘録

deviseの便利な機能の使い方

こんにちは。本日はdeviseでよく使う機能を見ていきたいと思います。

deviseではログインしていなければトップページにリダイレクトしたり、現在ログインしているユーザーが本人かどうか調べたりできるなどの便利な機能があります。


※deviseのインストール方法は過去記事を参考にしてください。
chi-kun.hatenablog.com

バージョン

Ruby '2.2.1'
Rails '4.2.1'
Devise '3.5.1'


フラッシュメッセージ

deviseではユーザーがログインに成功した時や失敗した時にフラッシュメッセージを表示することができます。
成功した場合は「notice」,
失敗した場合は「alert」です。

まずapplication.html.erbのヘッダー直下にフラッシュメッセージを表示させるために以下のコードを書きます。

# application.html.erb
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Sample</title>
        <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
        <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
        <%= csrf_meta_tags %>
    </head>
    <body>
      <%= render "layouts/header" %>

        <!-- ここから追加 -->
        <% flash.each do |key, value| %>
          <div class="alert alert-<%= key %>">
            <div class="container">
              <%= value %>
            </div>
          </div>
        <% end %>
        <!-- ここまで追加 -->

      <%= yield %>
    </body>
</html>

次にフラッシュメッセージの見栄えを良くするためscssファイルを編集します。

#application.css.scss
@import "bootstrap-sprockets";
@import "bootstrap";

body{
  padding-top: 50px;
}
/* エラーメッセージ */
.alert-notice {
  color: #3c763d;
  background-color: #dff0d8;
}
.alert-alert {
  background-color: #f2dede;
  color: #a94442;
}

そして新規登録とログインのリンクを表示しましょう。今回はヘッダーに表示したいとおもいます。

# _header.html.erb
<nav class="navbar navbar-default navbar-fixed-top">
  <div class="container">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Sample</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav navbar-right">
        <!-- ここから追加 -->
        <li><%= link_to "ログイン", new_user_session_path %></li>
        <li><%= link_to "新規登録", new_user_registration_path %></li>
        <!-- ここまで追加 -->
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>

それでは実際に見てみましょう。
まずは新規登録に成功した場合。

f:id:chi_kun:20160424193411p:plain

メールとパスワードを入れると...

f:id:chi_kun:20160430151241p:plain

きちんと表示されました。


authenticate_user!

サービスを作るときに、会員登録してなければアクセスできなくする機能を実装したいなと思うことがあると思います。
authenticate_user!を使えば、簡単に実現することができます。

まずは機能制限をしたいコントローラーに書きます。今回は新規投稿に制限をかけて見ましょう。

# posts_controller.rb
class PostsController < ApplicationController
  # ログイン必須
  before_action :authenticate_user!, only:[:new]

ではログアウトした状態で新規投稿アクションにアクセスしてみましょう。

f:id:chi_kun:20160430161445p:plain

新規投稿しようとするときちんとログインページに飛ばされていますね。


user_signed_in?

user_signed_in?ヘルパーを使えばユーザーがログインしているかどうか調べることができます。
ここではユーザーがログインしてれば新規投稿・ログアウトのリンクを、ログアウトしてれば新規登録・ログインのリンクを表示してみましょう。
if文で条件分岐します。

# _header.html.erb
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav navbar-right">
        <!-- ここから編集 -->
        <% if user_signed_in? %>
          <li><%= link_to "投稿", new_post_path %></li>
          <li><%= link_to "ログアウト", destroy_user_session_path, method: :delete %></li>
        <% else %>
          <li><%= link_to "ログイン", new_user_session_path %></li>
          <li><%= link_to "新規登録", new_user_registration_path %></li>
        <% end %>
        <!-- ここまで編集 -->
      </ul>
    </div>

では見てみましょう。

まずログイン前

f:id:chi_kun:20160430163359p:plain

そしてログイン中

f:id:chi_kun:20160430163518p:plain

きちんとヘッダーのリンク部分が変わっていますね。


current_user

current_userを使えばログインしているユーザーのオブジェクトを知ることができます。
今回はヘッダーにユーザーのメールアドレスを取得してみましょう。

# _header.html.erb
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav navbar-right">
        <% if user_signed_in? %>
          <!-- ここから追加 -->
          <li><%= link_to current_user.email, "#" %></li>
          <!-- ここまで追加 -->
          <li><%= link_to "投稿", new_post_path %></li>
          <li><%= link_to "ログアウト", destroy_user_session_path, method: :delete %></li>
        <% else %>
          <li><%= link_to "ログイン", new_user_session_path %></li>
          <li><%= link_to "新規登録", new_user_registration_path %></li>
        <% end %>
      </ul>
    </div>

すると...

f:id:chi_kun:20160430164757p:plain

きちんとユーザーのメールアドレスが表示されていますね。



本日は以上です。