Ruby and Rails

Ruby と Ruby on Rails のこと

Devise の Bootstrap 対応と日本語化

Bootstrap と親和性の高いログイン画面と、メッセージを日本語にする方法。

インストール

Gemfile に下記追加。

gem 'devise'
gem 'devise-bootstrap-views'
gem 'devise-i18n'
gem 'devise-i18n-views'

インストール。

$ bundle

Devise の準備

Devise のビューや、User モデルにカラムを追加。

$ rails g devise:install
$ rails g devise users

./app/views/layouts/application.html.erb に認証の成功や失敗のメッセージがでるように追加。

    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>

これだと見栄えが悪いので、下記にしている。

      <% if notice.present? %>
        <div class="alert alert-dismissable alert-success">
          <button type="button" class="close" data-dismiss="alert">&times;</button>
          <p><%= notice %></p>
        </div>
      <% end %>

      <% if alert.present? %>
        <div class="alert alert-dismissable alert-danger">
          <button type="button" class="close" data-dismiss="alert">&times;</button>
          <p><%= alert %></p>
        </div>
      <% end %>

./app/controllers/application_controller.rbbefore_action :authenticate_user! を追加。

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_action :authenticate_user!
end

RSpec 対応

次に RSpec でコントローラのテストを通るようにする ( How To: Stub authentication in controller specs · plataformatec/devise Wiki を参考にしています )。

spec/rails_helper.rb に下記。

module ControllerHelpers
  def sign_in(user = double('user'))
    if user.nil?
      allow(request.env['warden']).to receive(:authenticate!).and_throw(:warden, {:scope => :user})
      allow(controller).to receive(:current_user).and_return(nil)
    else
      allow(request.env['warden']).to receive(:authenticate!).and_return(user)
      allow(controller).to receive(:current_user).and_return(user)
    end
  end
end

RSpec.configure do |config|
  config.infer_spec_type_from_file_location!
  config.include Devise::TestHelpers, type: :controller
  config.include ControllerHelpers, type: :controller
end

あとはテストをしたいファイルに sign_in と書いてあげる。

  describe "GET index" do
    it "returns http success" do
      sign_in # これを追加
      get :index
      expect(response).to have_http_status(:success)
    end
  end

Bootstrap 対応

./app/assets/stylesheets/application.css に Devise 用 Bootstrap の CSS を追加。

*= require devise_bootstrap_views

日本語対応

$ rails g devise:views:locale ja
      create  config/locales/devise.views.ja.yml
$ rails g devise:views:bootstrap_templates
      create  app/views/devise
      create  app/views/devise/confirmations/new.html.erb
      create  app/views/devise/mailer/confirmation_instructions.html.erb
      create  app/views/devise/mailer/reset_password_instructions.html.erb
      create  app/views/devise/mailer/unlock_instructions.html.erb
      create  app/views/devise/passwords/edit.html.erb
      create  app/views/devise/passwords/new.html.erb
      create  app/views/devise/registrations/edit.html.erb
      create  app/views/devise/registrations/new.html.erb
      create  app/views/devise/sessions/new.html.erb
      create  app/views/devise/shared/_links.erb
      create  app/views/devise/unlocks/new.html.erb

config/application.rb で ja に設定。

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de
    config.i18n.default_locale = :ja

[おまけ] Bootstrap 対応ログアウト

ログアウトを Bootstrap の navbar に組み込んでいる。

font-awesome-rails も利用。

        <ul class="nav navbar-nav navbar-right">
          <% if user_signed_in? %>
            <li><a class="navbar-brand" data-method="delete" href="/users/sign_out" rel="nofollow" data-toggle="tooltip" data-placement="bottom"><%= fa_icon 'arrow-circle-right', text: "#{current_user.email} をログアウト", right: true %></a></li>
          <% end %>
        </ul>

関連