Ruby Weekly #372: 日本語サマリー
職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。
Highlights
Ruby 2.5 新機能まとめ。
begin
明示しなくてもdo/end
ブロックのrescue
else
ensure
ができるようになった。- 同一ネームスペース内で見つからなかった定数をルートネームスペースから探すのがなくなった。
- bundler 同梱。
- バックとレースのエラー発生行番号を一番下に出力するようになった。
yield_self
新規追加。String#delete_prefix
String#delete_suffix
新規追加。Array#unshift
の alias としてArray#prepend
新規追加。Array#push
の alias としてArray#append
新規追加。Hash#transform_keys
Hash#transform_keys!
新規追加。.
..
を除外したDir.children
Dir.each_child
新規追加。- ERB に binding を渡す手間を省いた
ERB#result_with_hash
新規追加。
Faktory バックグラウンドジョブ用サーバデーモンとそのワーカー用 faktory_worker_ruby gem リリース。Sidekiq 同様にウェブ UI とジョブ永続化(Facebook 製 RocksDB)機能付き。
FactoryGirl と FactoryGirlRails gem が FactoryBot と FactoryBotRails に改名。ユーザに不快感を与えないように、ジェンダー的に中性なネーミングにした。その裏に、Uber や Google のセクハラ・差別スキャンダルで非難を浴びてきた近年のシリコンバレーの影響があると思われる。
Configuration オブジェクト戦略いろいろ。
Hash
- YAML
OpenStruct
ActiveSupport::Configurable
知見
ミュテーションテストでより深く理解した絶対テストと相対テスト。
- 絶対テスト: 定数・リテラルと比較した
assert_equal
- 相対テスト:
<
>
<=
>=
や変数と比較したassert_equal
絶対テストは省略しがちだが、あったほうがミュテーションテストに強い。 例えば
#hash
をオーバーライドしたアルゴリズムは、assert_equal(object1, object2)
だけだと、アルゴリズムの固定値が書き換えられても、テストが落ちなくなる。ハッシュ値を固定値と比較した絶対テストがあるべし。- AUTOINCREMENT カラムでソートした scope は、
assert_equal([record1, record2], records)
だけだと、初期値が予期せぬ負の数値に書き換えられても落ちない。 id
カラムでソートした scope は、assert_equal([record1, record2], records)
だけだとorder(:id)
が書き換えられても落ちない。欠番を再利用する DB では不具合が起き得る。SQL 文の固定値と比較した絶対テストがあるべし。
モックは下記問題点がある。
expect
→allow
(setup
) →実行
順番が普段のsetup
→実行
→expect
と異なってて非直感的。- モックしたクラスと密結合。
- 再利用性が低い。
お手製 double
で全部解消。spy
はなおよし。
News
Ruby 2.5 以降は begin
明示しなくても do/end
ブロックの rescue
else
ensure
ができるようになった。
RSpec 3.7 Released: Now Integrates with Rails 5.1 System Tests
RSpec 3.7 は Rails システムテストに対応してる。これからは Feature スペックよりもシステムテスト推奨。Feature スペックと違って
- database-cleaner が不要。
- デフォ Selenium。
Rails の PhantomJS がようやく廃止となった。代わりに Selenium/Chrome Headless 導入。
Tutorial
プログラミング言語バージョン管理ツール asdf のインストール手順を紹介した、ブラジル RubyConf 元主催者 Fabio Akita 先生。rvm・rbenv と違って Elixir、Go、Node.js など多岐にわたる言語も一括管理。
Rails システムテストに移行した Table XI 社 Noel Rappin 先生。
- システムテストは Capybara でブラウザーを操作したテスト。
- Capybara の既存 RSpec テストも、システムテストに移行すれば、色々楽になる。Rails と同じプロセスで動くようになるから。
- 移行手順
- 各テストに
type: :system
メタデータ追加。 - テストファイルを spec/system フォルダーに移す。
- 原文の configuration 設置。
- 各テストに
- Circle CI 2.0 用設定は原文参照。
Rails アプリに Google reCAPTCHA 2 を設置する手順。
- Google reCAPTCHA 2 取得サイトでアプリを登録。
- ビューで reCAPTCHA の JavaScript ライブラリをロード。
<script>
要素のonload
コールバックで reCAPTCHA ウィジェットをロード。- コントローラの
before_action
で reCAPTCHA を承認。再利用できるように、concerns モジュールにて実装。 RecaptchaVerifier
サービスオブジェクト実装して、注入したGoogleRecaptcha
クラスに承認させる。GoogleRecaptcha
が Google reCAPTCHA API を叩くように実装。
React + Rails アプリを開発した Reverb 社は、クラサバ二重実装を避けるべく、React コンポーネントを Node.js で生成することになった。Rails ⇔ Node.js 通信は元々パフォーマンスの良い Unix ソケットだったが、各アプリサーバに React Rendering Engine (RRE) をデプロイする必要はあった。その手間を省くように gRPC + protocol buffer に移行することにした。
- .proto ファイルでインタフェース定義。
- protoc コンパイラーをインストール。
- grpc-tools gem で Ruby クライアント生成。
- Node 用 grpc ライブラリをインストール。
- Node 側サービス実装(原文コード参照)。
- Unicorn・Puma を使っている場合は、
after_fork
フックでクライアントを生成するように設定。
Rails バージョンアップ手順。
- 新規 Rails アプリ作成。
- 既存アプリで新規ブランチ切る。
- 新規 Rails アプリの gem を既存アプリの Gemfile にコピペ。既存 gem は必要に応じてバージョンアップ。
rails app:update
実行で config・bin ファイル更新。- テストのエラー修正。deprecation 忠告は無効にしておくこと。
- deprecation 忠告を有効にして、ひとつずつ解消。
- main ブランチにマージ。
Rails 5.1 アプリを作ってみた、ブラジル RubyConf 元主催者 Fabio Akita 先生。
- 新規 Rails アプリ生成手順
- webpack 採用手順
Rails 5.1 の大きな特徴はモダンな JavaScript・CSS への対応。
2 Ways to Test Eager Loading of ActiveRecord Associations in Rails
eager loading のテスト方法 2 つ。
association(:name).loaded?
ActiveSupport::Notifications
で発行クエリ数取得
Story
6 年ものレガシー Rails アプリに React を導入した話。
- モダンな JavaScript UI が必要となったのがきっかけ。
- jQuery でもできたが、React のほうがメンテしやすいし、ES6・ES5 相互対応でブラウザ間互換性が魅力的。
戦略。
- React 層をなるべく薄くし、routing は Rails に任せっきり(ページ間遷移は従来の HTTP)。
ActiveModel::Serializer
フル活用。モデルのデータだけでなく、ActiveRecord メソッドまで呼べて便利。
Opinion
何でもかんでも「魔術」と呼ぶのをやめよう、という主張。コミュニティの創造力の妨げになるから。
- 初心者には分からないからって「魔術」と呼んじゃダメ。
- モンキーパッチは良くない場合もあるが、「魔術」とはいえない。
- メタプロは「魔術」ではない。
これなら初めて「魔術」といえる。
class LandCruiserJ200Car end car = LandCruiserJ200Car.new # => #<Car model="Land Cruiser J200"> car.drive! # "wroom! wrrroooom!"
何も継承してないのにどこかから挙動を継承してる。つまりソースの追いようがないコード。
Tools
ActionCable テスト用 gem。Rails への PR としても出されてるが、Ruby Weekly 投稿時点では未マージ。
- 継承用
ActionCable::TestCase
とActionCable::Channel::TestCase
have_broadcasted_to
broadcast_to
RSpec マッチャー- Generator
Rails コード可読性向上 gem 集。
- サービスオブジェクト用 interactor
- デコレーター用 draper
- フォームオブジェクト用 virtus
- ビューモデル用 cells
- 例外発生時リトライ用 retryable
- Controller ボイラープレート隠蔽用 decent_exposure
- 日時グルーピング scope 用 groupdate
Code
Hanami 1.1 リリース。
belongs_to
has_one
has_many through:
アソシエーション- CLI は thor から hanami-cli に切り替えた
Hanami::Entity
のカスタムスキーマ定義- ブートするアプリを
HANAMI_APPS
環境変数で指定 - パスワードなどがログに残らないようにフィルター
rom-factory gem 新規リリース。FactoryBot(旧名 FactoryGirl)より 1.5 倍速く下記機能提供。
- 動的
sequence
- faker 同梱
- アソシエーション対応
- factory 継承