Ruby and Rails

Ruby と Ruby on Rails のこと

Devise で自明の「ログインしました」を出さない方法

Devise でログインすると「ログインしました」、ログアウトすると「ログアウトしました」と出るけど、画面を見れば自明なので出したくない。

特に「ログインしました」は何か操作するまでずっと出ているのが特に嫌。

その場合は ja.yml で '' して文言を消す。

devise:
    sessions:
        signed_in: ''
        signed_out: ''

この簡単な方法を最初思いつかず、

<script>
$('#notice').fadeOut(3000);
</script>

とかしようとしてた。

guard - ブラウザのリロードや RSpec の自動実行

ファイルを更新したら Chrome を自動でリロードしたり、RSpec を自動実行してくれるのが guard。

インストール

Gemfile に下記。

group :development, :test do
  gem 'guard-livereload'
  gem 'guard-rspec'
end

インストール。

$ bundle

Chrome 拡張機能 LiveReload

guard と連携して Chrome をリロードする LiveReload をインストール。

Guardfile を用意

guard がどんな時に何をするのか記述したものが Guardfile。

生成は下記。

$ bundle exec guard init

実行

$ bundle exec guard

これでファイルを更新するとブラウザが自動でリロードされ、RSpec が走ります。

guard が走ったら、Chrome の LiveReload ボタンを押す。

ものすごく分かりづらいんだけど、真ん中の白丸が黒丸になる。

ローカルの Chrome で LiveReload

開発環境がリモートにあり、ブラウザがローカルの場合。

( 例えば Macssh して開発環境に入っているが、ChromeMac 上の場合 )

SSH ポートフォワーディングする。

$ ssh -L 35729:localhost:35729  oooooooo@192.168.0.2

もしくは ~/.ssh/config に書いておく。

Host dev
  HostName     192.168.0.2
  User         oooooooo
  LocalForward 35729 localhost:35729
$ ssh dev

better_errors - エラー画面を便利にする

Rails に標準で入れてほしい better_errors。

エラー画面で REPL が使えます。変数を確認したりと便利。

インストール

Gemfile に下記。

group :development, :test do
  gem 'better_errors'
  gem 'binding_of_caller'
end

インストール。

$ bundle

REPL があるということは何でもできるため、localhost 以外ではデフォルトでは動きません。

そのため、リモート先に開発環境がある場合に、デフォルトでは better_errors が表示されません。

config/environments/development.rb に下記を書けば、192.168.0.0/9 からのアクセスの場合は better_errors が表示されます。

  BetterErrors::Middleware.allow_ip! '192.168.0.0/9'

charliesome/better_errors

font-awesome-rails は本当に Awesome

bokmann/font-awesome-rails を使うと、簡単に Font Awesome を導入できる。

インストール

Gemfile に追加。

gem 'font-awesome-rails'

インストール。

$ bundle

./app/assets/stylesheets/application.css に追加。

 *= require font-awesome

使い方

fa_icon の後ろに Font Awesome Icons の名前を書くだけ。

ただし、頭の fa- は不要。例えば fa-camera-retro なら camera-retro になる。

<%= fa_icon 'camera-retro' %>

横にテキストを追加するなら。

<%= fa_icon 'camera-retro', text: 'Take a photo' %>

テキストの右側に配置も可能。

<%= fa_icon 'chevron-right', text: 'Get started', right: true %>

アイコン同士の合成もできる。

<%= fa_stacked_icon 'twitter',  base: 'circle-o' %>
<%= fa_stacked_icon 'twitter',  base: 'sqare-o' %>
<%= fa_stacked_icon 'twitter',  base: 'sun-o' %>

class 指定も可能だし、4x と書けば 4 倍の大きさになる。

<%= fa_icon 'quote-left 4x', class: 'text-muted pull-left' %>

本当に便利。

おまけ : Evil Icons

Evil Icons も font-awsome-rails のように扱えます。

Devise に初期ユーザを追加

db/seeds.rb に下記を書く。

User.create(email: 'admin@example.com',   password: 'password')
User.create(email: 'manager@example.com', password: 'password')
User.create(email: 'user@example.com',    password: 'password')

下記で登録できる。

$ rake db:seed

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>

関連

New Relic

New Relic はパフォーマンスはもちろんのこと、脆弱性のある Rails のバージョンであれば指摘してくれたり、開発環境では unicorn じゃないほうがいいなどのアドバイスもくれる。

インストール

Sign Up

まずは New Relic に Sign Up。

newrelic.yml

New Relic の Account Settings の画面右下にある Download a clean configuration file から newrelic.yml ファイルをダウンロード。

newrelic.yml を Rails の config ディレクトリに置く。

そして newrelic.yml に書かれた「My Application」を自分のアプリ名に変更。

何箇所かにあるので置換。

$ sed -i 's/My Application/Your Project Name/' config/newrelic.yml

newrelic_rpm

Gemfile に追加。

gem 'newrelic_rpm'

インストール。

$ bundle

rails server を再起動し、http://localhost:3000/newrelic が見られれば成功。

New Relic のダッシュボード にも自分のアプリ名が出ているはず。

もし出ていない場合は log/newrelic_agent.log をチェック。

New Relic のグラフを保存

New Relic の無料版は 24 時間しかデータが保存されない。

下記方法を使えばスクリーンショットを保存しておくことができる。

New Relic のグラフを毎時チャットに貼り付ける - @kyanny's blog

newrelic_rpm のアップデート

よく newrelic_rpm はアップデートされている。

newrelic_rpm だけアップデートするには下記。

$ bundle update newrelic_rpm