Rails 5.1へのアップデート


Ruby on Rails 5.0系から5.1系へのアップデートに関するTipsです。

🏈 主な変更点

yarnのサポート

npmによるJavaScriptのライブラリをyarnで管理できます。これにより、npmで管理されたライブラリを気軽に利用できます。

bin/yarn installでnpmのライブラリをインストールできます。

webpackのサポート(任意)

--webpackオプションを付けると、webpackを使ってJSをコンパイルできます。
新規プロジェクトの場合は次のように--webpackをつけると有効になります。

rails new プロジェクト名 --webpack

既存プロジェクトに導入する場合はGemfileに次のコードを追加してください。

em 'webpacker'

そして次のコマンドを実行します。

bin/rails webpacker:install

jQueryに依存しなくなった

RailsのJavaScript実装のjquery-ujsがjQueryではなく、pure JavaScriptになり「rails-ujs」となるそうです。

インテグレーションが容易に

SystemTestCaseを使うことで、インテグレーションテストを実装しやすくなりました。

require 'application_system_test_case'
class Users::CreateTest < ApplicationSystemTestCase
test 'adding a new user' do
visit users_path
click_on 'New User'
fill_in 'Name', with: 'Arya'
click_on 'Create User'
assert_text 'Arya'
end
end

標準で作成されるApplicationSystemTestCaseでCapybaraのドライバやブラウザ、画面解像度を設定できます。

require test_helper
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
end

config/secrets.ymlを暗号化

config/secrets.ymlを次のコマンドで暗号化します。

bin/rails secrets:setup

実行するとconfig/secrets.yml.key(鍵)とconfig/secrets.yml.enc(暗号化されたファイル)が生成されます。
config/secrets.yml.keyは本番環境の環境変数RAILS_MASTER_KEYに設定します。

Action Mailerにパラメータを渡せる

Action Mailerにパラメータを渡せるので、DRYに書きやすくなりました。

class InvitationsMailer < ApplicationMailer
before_action { @inviter, @invitee = params[:inviter], params[:invitee] }
before_action { @account = params[:inviter].account }
def account_invitation
mail subject: #{@inviter.name} invited you to their Basecamp (#{@account.name})
end
end
InvitationsMailer.with(inviter: person_a, invitee: person_b).account_invitation.deliver_later

directed routes

routes.rbに次のようなHelperを書くことができるようになりました。

direct :commentable do |model|
[ model, anchor: model.dom_id ] # modelの内容で分岐することもできます
end
direct :main do
{ controller: 'pages', action: 'index', subdomain: 'www' }
end

resolved routes

routes.rbに次のようなルーティングを記述できるようになりました。

resource :basket
direct(class: Basket) { [:basket] }

すると次のようにform側を記述できます。

<%= form_for @basket do |form| %>
...
<% end %>

form_withメソッド

URLを直接指定する

<%= form_with url: posts_path do |form| %>
...
<% end %>

生成されるHTMLは次のようになります。

<form action=/posts method=post data-remote=true>
<input type=text name=post[title]>
</form>

モデルオブジェクトを渡す

<%= form_with model: Post.first do |form| %>
...
<% end %>

生成されるHTMLは次のようになります。

<form action=/posts/1 method=post data-remote=true>
<input type=hidden name=_method value=patch>
<input type=text name=post[title] value=<the title of the post>>
</form>

Time型もタイムゾーンを考慮

Datetime型だけでなく、Time型もタイムゾーンを考慮した実装に変わりました。

# DatetimeとTime型の両方でTimezoneをつける
config.active_record.time_zone_aware_types = %i[datetime time]
# Rails 5以前のようにDatetime型のみTimezoneをつける
config.active_record.time_zone_aware_types = %i[datetime]

🏀 アップデートの手順

  • Gemfileのrailsバージョンを5.1にアップデート
  • HashWithIndifferentAccessは速度の問題があるため、ActiveSupport::HashWithIndifferentAccessに移行
  • config/secrets.ymlを使っている場合は、キーをシンボルで読み込むようにする

🍄 参考リンク

📚 おすすめの書籍

🖥 サーバについて

このブログでは「Cloud Garage」さんのDev Assist Program(開発者向けインスタンス無償提供制度)でお借りしたサーバで技術検証しています。 Dev Assist Programは、開発者や開発コミュニティ、スタートアップ企業の方が1GBメモリのインスタンス3台を1年間無料で借りれる心強い制度です!(有償でも1,480円/月と格安)