Ruby and Rails

Ruby と Ruby on Rails のこと

目次

開発効率化

rails コマンド

UI

認証

メール

デバッグ

RSpec

パフォーマンス

いろいろ

Rails 5 に yarn で Bootswatch 4 beta 入れた

Rails 4 時代は

maxim/bootswatch-rails: Bootswatches converted to SCSS ready to use in Rails asset pipeline.

にお世話になったけど、Rails 5.1.4 なので yarn を使って Bootswatch 4.0.0-alpha6 を入れてみる。

Bootswatch のバージョン確認してインストール

$ yarn info bootswatch | less
yarn info v1.0.2
{ name: 'bootswatch',
  description: 'Bootswatch is a collection of themes for Bootstrap.',
  'dist-tags':
   { latest: '3.3.7',
     next: '4.0.0-alpha.6' },
  versions:
   [ '3.0.0',
     '3.2.0',
     '3.3.0',
     '3.3.1',
     '3.3.2',
     '3.3.4',
     '3.3.5',
     '3.3.6',
     '3.3.7',
     '4.0.0-alpha.6' ],
以下略

4.0.0-alpha.6 があるので入れる。

$ yarn add bootswatch@4.0.0-alpha.6

Rails に Bootswatch 導入

thomaspark/bootswatch: Themes for Bootstrap

は Bootswatch 3 の情報なので ( 2017-9-23 時点 )、Branch を v4 にする。

thomaspark/bootswatch at v4

/app/assets/stylesheets にある application.scss を application.scss に mv して

@import "bootswatch/theme/variables";
@import "bootstrap/scss/bootstrap";
@import "bootswatch/theme/bootswatch";

と書く。

application.scss に書く

なんのテーマを入れようかな。

Bootswatch: Free themes for Bootstrap

3 に比べて Litera、Lux、Materia、Minty、Pulse が増えてる。3 のテーマに飽きていたので嬉しい。

新しい Litera 試してみる。

@import "bootswatch/litera/variables";
@import "bootstrap/scss/bootstrap";
@import "bootswatch/litera/bootswatch";

反映されていい感じになった。

CSS の微調整

自分の書き方が悪いのか、リンクのホバー時に背景黒でリンク赤とか、a.btn.btn-primary のリンク色が暗いとかあったので application.scss に追記。

ほかに h1 がフォント大きすぎと body に文字くっつきすぎを調整。

h1 {
  font-size: 1.2rem;
}

body {
  padding: 1rem;
}

a.btn {
  color: white;
}

a:hover {
  background-color: transparent;
}

余談

開発中のメールアドレスを安全にする mail_safe

開発中にメールアドレスがうっかり外に出ないようにしたい。でも、メールが送信されるのは確認したい。

そんな時は

myronmarston/mail_safe

を使うことで、メールアドレスを安全に変換してくれます。

例えば foo@example.com を「自分のアカウント+foo-AT-example.com@gmail.com」のように置換してくれます。

( gmail.com は自分のアカウントの後ろに「+何か」と書いても自分に届くんです )

設定 1 - 全メールを安全に

config/initializers/mail_safe.rb に

if defined?(MailSafe::Config)
    MailSafe::Config.replacement_address = lambda { |address| 
      "自分のアカウント+#{address.gsub(/[\w\-.]/, '_')}@gmail.com"
    }
end

と書けば、全メールを

自分のアカウント+____@____@gmail.com

にしてくれます。

設定 2 - 一部メールはそのままに

例えば社内の @exmaple.com と @example.net、それと full-address@example.info だけはそのまま送信したいこともあります。

その場合は下記。

if defined?(MailSafe::Config)
    MailSafe::Config.internal_address_definition = lambda { |address|
      address =~ /.*@example\.com/i ||
      address =~ /.*@example\.net/i ||
      address == 'full-address@example.info'
    }

  MailSafe::Config.replacement_address = lambda { |address|
    "自分のアカウント+#{ address.gsub('@', '-AT-') }@gmail.com"
  }
end

ちなみに To: が test@example.com なら

自分のアカウント+test-AT-example.com@gmail.com

のように、誰に送ったか分かるようにしています。

Bootstrap の form を書く手間がゼロになる Rails Bootstrap Forms

Bootstrap を Rails に組み込んだだけ では、form_for や form_tag を書く時に class: 'btn btn-primary' とか書かないといけない。

bootstrap-ruby/rails-bootstrap-forms なら form_forbootstrap_form_for と書くだけ。

面倒な class を書かなくても Bootstrap が適用されます。

<%= bootstrap_form_for(@user) do |f| %>
  <%= f.email_field :email %>
  <%= f.password_field :password %>
  <%= f.check_box :remember_me %>
  <%= f.submit "Log In" %>
<% end %>

インストール

Gemfile に下記。

gem 'bootstrap_form'

インストール。

$ bundle

あとは app/assets/stylesheets/application.css に下記を追加すれば OK。

/*
 *= require rails_bootstrap_forms
 */

Ruby と Rails の便利な書き方

a ||= b と a || b

a が nil なら初期値を入れたい場合。

a = nil
a = 100 if a.nil? # => 100

a = nil
a ||= 100 #=> 100

と書けます。通称 nil ガード。

nil ガードの逆。すでに値が入っている場合に書き換えたいなら。

a = 100
a = 200 if a.present? #=> 200

a = 100
a || 200 #=> 200

と書けます。a が nil なら nil のまま。

Rails.root

Rails.root.join('tmp', 'foo', 'bar')

Rails.root / 'tmp/foo/bar'

と書けます。

try にメソッドの引数やハッシュのキーを渡す

メソッドの引数

date.present? ? date.strftime('%Y-%m-%dT%T') : nil

date.try(:strftime, '%Y-%m-%dT%T')

と書けます。

ハッシュのキー

ハッシュがあるかどうかは :[] を使います。

html.match(%r|^(?<body>.+?)$|).try(:[], :body)

参考文献

rake assets:precompile の RSpec を書く

bundle update して開発してカバレッジも 100% でテストも全部通った、さて、本番環境にデプロイ!と思ったら

$ rake assets:precompile
rake aborted!
NoMethodError: undefined method `[]' for nil:NilClass

とコケた。

less-rails-bootstrap が古くて、最新 sprockets と相性が悪かったみたい。

ということで assets:precompile も CI に含める。

$ cat spec/tasks/rake_assets_spec.rb
require 'rails_helper'

describe 'rake assets:precompile' do
  before :all do
    Rails.application.load_tasks
    Rake::Task.define_task(:environment)
  end

  it 'assets:clean' do
    expect{ Rake::Task['assets:clean'].invoke }.not_to raise_exception
  end

  it 'assets:precompile' do
    expect{ Rake::Task['assets:precompile'].invoke }.not_to raise_exception
  end
end

letter_opener と letter_opener_web

letter_opener 便利

letter_opener は送信したメールの確認に便利ですよね。

送信したメールの分だけスパパパパンとブラウザで開いてくれて。

インストール

Gemfile に下記。

gem 'letter_opener', group: :development

インストール。

$ bundle

config/environments/development.rb に下記。

config.action_mailer.delivery_method = :letter_opener

letter_opener_web も便利

ただし letter_opener はリモートで開発していると使えないことが。

例えば Mac の iTerm から Linux サーバにリモート接続して、ブラウザが Mac にある場合。

letter_opener はリモート先の Linux でメールを開いている。なので見えない。

そんな時は letter_opener_web が便利。

デフォルトでは localhost:3000/letter_opener/ にアクセスすることで

f:id:oooooooo:20150512232413p:plain

な感じで見ることができます ( デモ )。

インストール

Gemfile に下記。

gem 'letter_opener_web', group:  :development

インストール。

$ bundle

config/environments/development.rb に下記。

config.action_mailer.delivery_method = :letter_opener_web

要は letter_opener の部分を letter_opener_web にするだけ。

最後に config/routes.rb に下記。

Your::Application.routes.draw do
  if Rails.env.development?
    mount LetterOpenerWeb::Engine, at: '/letter_opener'
  end
end

/letter_opener は長いので /lo にしています。

短いし、lo で反応する人を見つけることができて便利です。