suin.io

【手順書】Rails+devise+bootstrap+slimで実装するユーザ認証機能

suin2016年8月22日

本稿ではRuby on Railsのユーザ認証機能をdeviseを使って実装する手順を説明します。

本稿のゴール

  • Ruby on Rails 4.2.6でユーザの新規登録・ログインなどの機能を実装する。
  • CSSフレームワークにはBootstrapを用いる。
  • テンプレートエンジンにはSlimを用いる。
  • deviseのビューを日本語に対応する。

必要なgemをインストールする

Gemfileに以下を追加します:

Gemfile
gem 'slim-rails'
gem 'bootstrap-sass'

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

gemをインストールします:

$ bundle

deviseのインストールとセットアップ

下記コマンドを実行してdeviseをRailsにインストールします:

$ rails generate devise:install
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml
===============================================================================

Some setup you must do manually if you haven't yet:

  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:

       config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

     In production, :host should be set to the actual host of your application.

  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root to: "home#index"

  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

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

  4. You can copy Devise views (for customization) to your app by running:

       rails g devise:views

===============================================================================

config/environments/development.rbに以下を追加します:

config/environments/development.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

これは、メール本文からアプリへリンクする際のURLに使われます。/etc/hostsなどで開発環境にホスト名を指定している場合は、hostlocalhostをお使いのホスト名にします。

ログイン後やログアウト後のリダイレクト先になるトップページを作ります:

$ rails generate controller Welcome index
      create  /controllers/welcome_controller.rb
       route  get 'welcome/index'
      invoke  slim
      create    /views/welcome
      create    /views/welcome/index.html.slim
      invoke  rspec
      create    spec/controllers/welcome_controller_spec.rb
      create    spec/views/welcome
      create    spec/views/welcome/index.html.slim_spec.rb
      invoke  helper
      create    /helpers/welcome_helper.rb
      invoke    rspec
      create      spec/helpers/welcome_helper_spec.rb
      invoke  assets
      invoke    coffee
      create      /assets/javascripts/welcome.coffee
      invoke    scss
      create      /assets/stylesheets/welcome.scss

routes.rbのroot 'welcome#index'のコメントアウトを外します:

routes.rb
  # You can have the root of your site routed with "root"
  root 'welcome#index'

認証情報を保存するためにユーザのモデルを生成します:

$ rails generate devise User
      invoke  active_record
      create    db/migrate/20160812123423_devise_create_users.rb
      create    /models/user.rb
      invoke    rspec
      create      spec/models/user_spec.rb
      invoke      factory_girl
      create        spec/factories/users.rb
      insert    /models/user.rb
       route  devise_for :users

ユーザ登録画面やログイン画面のビューを生成します:

$ rails generate devise:views
      invoke  Devise::Generators::SharedViewsGenerator
      create    /views/devise/shared
      create    /views/devise/shared/_links.html.erb
      invoke  form_for
      create    /views/devise/confirmations
      create    /views/devise/confirmations/new.html.erb
      create    /views/devise/passwords
      create    /views/devise/passwords/edit.html.erb
      create    /views/devise/passwords/new.html.erb
      create    /views/devise/registrations
      create    /views/devise/registrations/edit.html.erb
      create    /views/devise/registrations/new.html.erb
      create    /views/devise/sessions
      create    /views/devise/sessions/new.html.erb
      create    /views/devise/unlocks
      create    /views/devise/unlocks/new.html.erb
      invoke  erb
      create    /views/devise/mailer
      create    /views/devise/mailer/confirmation_instructions.html.erb
      create    /views/devise/mailer/password_change.html.erb
      create    /views/devise/mailer/reset_password_instructions.html.erb
      create    /views/devise/mailer/unlock_instructions.html.erb

ビューをBootstrap化する

deviseがデフォルトで生成してくれるビューはCSSフレームワークを使っていないので、別gemのdevise-bootstrap-viewsを用い、deviseのビューをBootsrap化します。下記コマンドを実行すると、各ビューがBootstrapのテンプレートに置き換わります。Overwrite (略).html.erb? (enter "h" for help) [Ynaqdh]と聞かれるのでaと入力します。

$ rails generate devise:views:bootstrap_templates
       exist  /views/devise
    conflict  /views/devise/confirmations/new.html.erb
Overwrite /app/app/views/devise/confirmations/new.html.erb? (enter "h" for help) [Ynaqdh] a
       force  /views/devise/confirmations/new.html.erb
    conflict  /views/devise/mailer/confirmation_instructions.html.erb
       force  /views/devise/mailer/confirmation_instructions.html.erb
    conflict  /views/devise/mailer/reset_password_instructions.html.erb
       force  /views/devise/mailer/reset_password_instructions.html.erb
    conflict  /views/devise/mailer/unlock_instructions.html.erb
       force  /views/devise/mailer/unlock_instructions.html.erb
    conflict  /views/devise/passwords/edit.html.erb
       force  /views/devise/passwords/edit.html.erb
    conflict  /views/devise/passwords/new.html.erb
       force  /views/devise/passwords/new.html.erb
    conflict  /views/devise/registrations/edit.html.erb
       force  /views/devise/registrations/edit.html.erb
    conflict  /views/devise/registrations/new.html.erb
       force  /views/devise/registrations/new.html.erb
    conflict  /views/devise/sessions/new.html.erb
       force  /views/devise/sessions/new.html.erb
    conflict  /views/devise/shared/_links.html.erb
       force  /views/devise/shared/_links.html.erb
    conflict  /views/devise/unlocks/new.html.erb
       force  /views/devise/unlocks/new.html.erb

erbをslimにする

deviseが生成するビューはerbになりますが、テンプレートエンジンはslimを使いたいので、html2slimを使ってerbからslimに一括変換します:

gem install html2slim
for file in app/views/devise/**/*.erb; do erb2slim $file ${file%erb}slim && rm $file; done

日本語のビューを生成する

デフォルトではビューが英語になるので、日本語の翻訳ファイルを生成して日本語対応します:

$ rails generate devise:views:locale ja
      create  config/locales/devise.views.ja.yml

レイアウトのBootstrap化

ここからはレイアウトをBootstrapにする方法になります。まず、application.cssを削除して、application.scssを作ります。

$ mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
app/assets/stylesheets/application.scss
/*
 *= require_self
 *= require_tree .
 */
@import "bootstrap-sprockets";
@import "bootstrap";
@import "devise_bootstrap_views";

次に、app/assets/stylesheets/common.scssを作り、アプリ独自のスタイルを定義します:

app/assets/stylesheets/common.scss
body {
  padding-top: 70px;
  padding-bottom: 30px;
}

BootstrapのJavaScriptを読み込むために<app/assets/javascripts/application.jsに以下を追加します:

//= require bootstrap-sprockets

最後に、レイアウトテンプレートを作ります:

app/views/layouts/application.html.slim
doctype html
html
  head
    meta charset="utf-8"
    title My App
    meta name="viewport" content="width=device-width, initial-scale=1.0"
    = stylesheet_link_tag    "application", media: 'all', 'data-turbolinks-track' => true
    = javascript_include_tag "application", 'data-turbolinks-track' => true
    = csrf_meta_tags

  body
    nav.navbar.navbar-default.navbar-fixed-top
      .container
        .navbar-header
          button.navbar-toggle.collapsed aria-controls="navbar" aria-expanded="false" data-target="#navbar" data-toggle="collapse" type="button"
            span.sr-only Toggle navigation
            span.icon-bar
            span.icon-bar
            span.icon-bar
          = link_to 'プロジェクト名', root_path, class: 'navbar-brand'
        #navbar.navbar-collapse.collapse
          ul.nav.navbar-nav
            li = link_to 'リンク1', root_path
            li = link_to 'リンク2', root_path
            li = link_to 'リンク3', root_path
          ul.nav.navbar-nav.navbar-right
            - if user_signed_in?
              li.dropdown
                a.dropdown-toggle aria-expanded="false" aria-haspopup="true" data-toggle="dropdown" href="#" role="button"
                  = current_user.email
                  span.caret
                ul.dropdown-menu
                  li = link_to 'ログアウト', destroy_user_session_path, method: :delete
            - else
              li = link_to 'ログイン', new_user_session_path
    .container
      = yield

最後に、https://localhost:3000/users/sign_upにアクセスしてアカウント登録画面が表示されていればdeviseの組み込みは完了となります。

Rails+devise+slim+bootsrapで作られたアカウント登録画面

まとめ

本稿ではRailsでdevise・Bootsrap・Slimを用いて認証機能を実装する手順を紹介しました。手順は多いですがコードをほとんど書かずに認証機能が実装できるのは楽で良いですね。

RELATED POSTS