rastam on rails

東京在住のマレーシア人 Rubyist

Ruby Weekly #372: 日本語サマリー

職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。

rubyweekly.com

Highlights

10 New Features in Ruby 2.5

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 新規追加。

Introducing Faktory: A New Background Job System

Faktory バックグラウンドジョブ用サーバデーモンとそのワーカー用 faktory_worker_ruby gem リリース。Sidekiq 同様にウェブ UI とジョブ永続化(FacebookRocksDB)機能付き。

FactoryGirl Has Been Renamed to FactoryBot

FactoryGirl と FactoryGirlRails gem が FactoryBotFactoryBotRails に改名。ユーザに不快感を与えないように、ジェンダー的に中性なネーミングにした。その裏に、UberGoogle のセクハラ・差別スキャンダルで非難を浴びてきた近年のシリコンバレーの影響があると思われる。

Creating Configuration Objects in Ruby

Configuration オブジェクト戦略いろいろ。

  • Hash
  • YAML
  • OpenStruct
  • ActiveSupport::Configurable

知見

  • 環境変数が散らばらないように、YAML で集約。
  • Hash#merge Hash#dig で優先順位どおりに適用。
  • rom-rb でコンフィグの全種類を管理。

Relative Testing vs Absolute Testing

ミュテーションテストでより深く理解した絶対テストと相対テスト。

  • 絶対テスト: 定数・リテラルと比較した assert_equal
  • 相対テスト: < > <= >= や変数と比較した assert_equal

絶対テストは省略しがちだが、あったほうがミュテーションテストに強い。 例えば

  1. #hash をオーバーライドしたアルゴリズムは、assert_equal(object1, object2) だけだと、アルゴリズムの固定値が書き換えられても、テストが落ちなくなる。ハッシュ値を固定値と比較した絶対テストがあるべし。
  2. AUTOINCREMENT カラムでソートした scope は、assert_equal([record1, record2], records) だけだと、初期値が予期せぬ負の数値に書き換えられても落ちない。
  3. id カラムでソートした scope は、assert_equal([record1, record2], records) だけだと order(:id) が書き換えられても落ちない。欠番を再利用する DB では不具合が起き得る。SQL 文の固定値と比較した絶対テストがあるべし。

Replacing Mocks With Hand-Written Test Doubles

モックは下記問題点がある。

  • expectallowsetup) → 実行 順番が普段の setup実行expect と異なってて非直感的。
  • モックしたクラスと密結合。
  • 再利用性が低い。

お手製 double で全部解消。spy はなおよし。

News

Ruby 2.5 Allows 'rescue/else/ensure' Inside 'do/end' Blocks

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 スペックと違って

PhantomJS Replaced with Chrome Headless in Rails

Rails の PhantomJS がようやく廃止となった。代わりに Selenium/Chrome Headless 導入。

Tutorial

Replacing RVM/rbenv with ASDF

プログラミング言語バージョン管理ツール asdf のインストール手順を紹介した、ブラジル RubyConf 元主催者 Fabio Akita 先生。rvm・rbenv と違って Elixir、Go、Node.js など多岐にわたる言語も一括管理。

A Quick Guide to Rails System Tests in RSpec

Rails システムテストに移行した Table XI 社 Noel Rappin 先生。

  • システムテストは Capybara でブラウザーを操作したテスト。
  • Capybara の既存 RSpec テストも、システムテストに移行すれば、色々楽になる。Rails と同じプロセスで動くようになるから。
  • 移行手順
    1. 各テストに type: :system メタデータ追加。
    2. テストファイルを spec/system フォルダーに移す。
    3. 原文の configuration 設置。
  • Circle CI 2.0 用設定は原文参照。

DIY Google reCAPTCHA with Rails

Rails アプリに Google reCAPTCHA 2 を設置する手順。

  1. Google reCAPTCHA 2 取得サイトでアプリを登録。
  2. ビューで reCAPTCHA の JavaScript ライブラリをロード。
  3. <script> 要素の onload コールバックで reCAPTCHA ウィジェットをロード。
  4. コントローラの before_action で reCAPTCHA を承認。再利用できるように、concerns モジュールにて実装。
  5. RecaptchaVerifier サービスオブジェクト実装して、注入した GoogleRecaptcha クラスに承認させる。
  6. GoogleRecaptchaGoogle reCAPTCHA API を叩くように実装。

Bridging Rails and Node.js with gRPC

React + Rails アプリを開発した Reverb 社は、クラサバ二重実装を避けるべく、React コンポーネントを Node.js で生成することになった。Rails ⇔ Node.js 通信は元々パフォーマンスの良い Unix ソケットだったが、各アプリサーバに React Rendering Engine (RRE) をデプロイする必要はあった。その手間を省くように gRPC + protocol buffer に移行することにした。

  1. .proto ファイルでインタフェース定義。
  2. protoc コンパイラーをインストール。
  3. grpc-tools gem で Ruby クライアント生成。
  4. Node 用 grpc ライブラリをインストール。
  5. Node 側サービス実装(原文コード参照)。
  6. Unicorn・Puma を使っている場合は、after_fork フックでクライアントを生成するように設定。

A 7-Step Approach to Rails Upgrades

Rails バージョンアップ手順。

  1. 新規 Rails アプリ作成。
  2. 既存アプリで新規ブランチ切る。
  3. 新規 Rails アプリの gem を既存アプリの Gemfile にコピペ。既存 gem は必要に応じてバージョンアップ。
  4. rails app:update 実行で config・bin ファイル更新。
  5. テストのエラー修正。deprecation 忠告は無効にしておくこと。
  6. deprecation 忠告を有効にして、ひとつずつ解消。
  7. main ブランチにマージ。

Trying Out Rails 5.1.x

Rails 5.1 アプリを作ってみた、ブラジル RubyConf 元主催者 Fabio Akita 先生。

  • 新規 Rails アプリ生成手順
  • webpack 採用手順

Rails 5.1 の大きな特徴はモダンな JavaScriptCSS への対応。

2 Ways to Test Eager Loading of ActiveRecord Associations in Rails

eager loading のテスト方法 2 つ。

  1. association(:name).loaded?
  2. ActiveSupport::Notifications で発行クエリ数取得

Story

Integrating React in a 6+ Year Old Rails App

6 年ものレガシー Rails アプリに React を導入した話。

  • モダンな JavaScript UI が必要となったのがきっかけ。
  • jQuery でもできたが、React のほうがメンテしやすいし、ES6・ES5 相互対応でブラウザ間互換性が魅力的。

戦略。

  • React 層をなるべく薄くし、routing は Rails に任せっきり(ページ間遷移は従来の HTTP)。
  • ActiveModel::Serializer フル活用。モデルのデータだけでなく、ActiveRecord メソッドまで呼べて便利。

Opinion

Please Stop Calling It 'Magic'

何でもかんでも「魔術」と呼ぶのをやめよう、という主張。コミュニティの創造力の妨げになるから。

  • 初心者には分からないからって「魔術」と呼んじゃダメ。
  • モンキーパッチは良くない場合もあるが、「魔術」とはいえない。
  • メタプロは「魔術」ではない。

これなら初めて「魔術」といえる。

class LandCruiserJ200Car
end

car = LandCruiserJ200Car.new
# => #<Car model="Land Cruiser J200">
car.drive! # "wroom! wrrroooom!"

何も継承してないのにどこかから挙動を継承してる。つまりソースの追いようがないコード。

Tools

Action Cable Testing Utilities

ActionCable テスト用 gem。Rails への PR としても出されてるが、Ruby Weekly 投稿時点では未マージ。

  • 継承用 ActionCable::TestCaseActionCable::Channel::TestCase
  • have_broadcasted_to broadcast_to RSpec マッチャー
  • Generator

7 Gems Which Will Make Your Rails Code Look Awesome

Rails コード可読性向上 gem 集。

  1. サービスオブジェクト用 interactor
  2. デコレーター用 draper
  3. フォームオブジェクト用 virtus
  4. ビューモデル用 cells
  5. 例外発生時リトライ用 retryable
  6. Controller ボイラープレート隠蔽用 decent_exposure
  7. 日時グルーピング scope 用 groupdate

Code

Hanami 1.1 Released

Hanami 1.1 リリース。

  • belongs_to has_one has_many through: アソシエーション
  • CLI は thor から hanami-cli に切り替えた
  • Hanami::Entity のカスタムスキーマ定義
  • ブートするアプリを HANAMI_APPS 環境変数で指定
  • パスワードなどがログに残らないようにフィルター

rom-factory: A Data Generator for Ruby Object Mapper (ROM)

rom-factory gem 新規リリース。FactoryBot(旧名 FactoryGirl)より 1.5 倍速く下記機能提供。

  • 動的 sequence
  • faker 同梱
  • アソシエーション対応
  • factory 継承