rastam’s blog

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

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

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

http://rubyweekly.com/issues/374rubyweekly.com

Highlights

How We Switched From Sprockets to Webpack

下記理由で Sprockets から Webpack に移行した LearnZillion 社。

  • Sprockets が重い。
  • ES6 欲しさ(Sprockets にもあるが、未だに experimental)。
  • Sprockets が提供してくれない機能欲しさ。
  • Webpack が Rails Way となった。

移行計画

  1. 準備フェーズ
    • Webpacker 追加
    • 環境構築
    • Nginx、capistrano 設定
    • デプロイ
  2. 移行フェーズ
    • Rails asset 用 gem を NPM パッケージで置換
    • アピリコードを Webpack に移行
    • 必要に応じて Webpack 設定修正
  3. クリーンアップフェーズ
    • Rails asset 用 gem 削除
    • Sprockets 設定削除
    • Webpack バンドル最適化

問題点

コード豊富なので原文参照。

Upgrading Kickstarter to Rails 5

9 年ものレガシー Rails アプリを Rails 5 にバージョンアップした Kickstarter 社。

  1. 段階的アップグレード
    • Rails 4.2.8 → 4.2.9 などのマイナーパッチ
    • Ruby 2.25 → 2.4.x
  2. リリースノートに従った修正
  3. gem を v5 にアップグレード
  4. Rails 4.2 にマージできる修正を master ブランチにマージ
  5. Rails 5 専用ブランチを CI グリーンに
  6. Rails 5 専用ブランチの deprecation 忠告撲滅
  7. Rails 5 専用ブランチを手動で動かす
    • テストでカバーできてない問題特定のため
  8. master ブランチで今までの修正をバックポート
  9. 各機能の開発チームに自分の機能をテストしてもらう
  10. staging 環境にデプロイ
  11. 本番デプロイ
    • カスタマーサポートからのバグチケ消化
  12. 振り返り

結果

  • 見積もりどおりの 3 ヶ月で完了
  • 大規模ダウンタイムなし
  • カスタマーサポートのバグチケ対応計画たてとけばよかった
  • いろいろ学習できた
  • 影響範囲の最も広かった変更点は HashWithIndifferentAccess を継承しなくなった ActionController::ParametersHash を継承していることを前提にしたコードがいっぱいあったから。
  • モバイルアプリへの影響は少なかったが、予想しなかった。ネイティヴチームのエンジニア巻き込んどけばよかった。

Ruby Performance Profiling: An Unorthodox Approach

API の重いリクエストで悩まされた Kollegorna 社は、フレイムグラフ見てもネックが特定できなかった。そこでクラス単位でメソッドをベンチマークしてくれる ClassProfiler gem を作ることに。%の最も高いメソッドの中で呼ばれるクラスを次々とベンチマークすることで、やっと犯人に辿り着いた。

Why Aren't We Using More Service Objects Already

先週サービスオブジェクトの使いすぎを否定した Avdi Grimm 先生への反論。

  • モジュールメソッドだとどんどん増えていき、結局 junk drawer になる。
  • 筆者の経験では、サービスオブジェクトが統一したコードへと繋がった。
  • サービスオブジェクトを支える ActiveInteraction gem まで作った。

Multiverse: Manage Multiple Databases in Rails Apps

Rails アプリの多数データベース用 gem。

News

Ruby Versions Used in Commercial Projects in 2017

Semaphore CI ユーザが採用している Ruby バージョン別分布。

  • 85% は Ruby 2.0 以上。
  • 最新バージョン (2.4) の採用は例年に比べて低い。
  • Ruby 2.1 は EOL 済みなので早めにバージョンアップするように推奨。

JRuby 9.1.14.0 Released

JRuby 9.1.14.0 リリース。

RubyGems 2.7.2 Released: A Bugfix Release

RubyGems 2.7.2 リリース。

  • bundle gem コマンドで新規 gem 生成できなくなっていたバグ解消。
  • git がインストールされていない環境でエラっていたバグ解消。

Tutorial

Interactors in Ruby: Easy As Cake, Simple As Pie

インタラクターデザパタinteractor gem の紹介。

  • Fat Controller の各工程をそれぞれサービスオブジェクトに抽出して、 Interactor モジュールを include
  • Interactor::Organizerinclude したオブジェクトでサービスオブジェクトの呼び出し順番を定義。
  • Interactor が提供してくれる before around after フックでトランザクションを張ったりする。
  • gem は非常に計量(ソースが小さい)。
  • Interactor::Organizer に並べたサービスオブジェクトは Context オブジェクトを共有するのがちょっとグローバル変数っぽくて要注意。
  • gem は validation 仕組みを提供してくれないので、筆者が validation 用 Interactor を提案した。

How 'require' Loads A Gem

$LOAD_PATH に載っていないのに gem を require できるようにしてくれる RubyGems コードリーディング。Kernel#require のモンキーパッチで、LoadError 発生時の rescue ブロックで、インストール済み gem の中から探す。見つけた場合、$LOAD_PATH に追加し、require 再挑戦。

Get 80% Smaller Rails Page Sizes with Rack Deflate

Rack::Deflate ミドルウェアRails レスポンスを gzip 圧縮してサイズを 80% 減らした Richard Schneeman 先生。

Quick Tip: A Pitfall of The &. Operator

&. 演算子の罠。< などの評価順番が変わっちゃうから要注意。(原文コード参照)

How to Partition and Conquer a Large Postgres Table

数百万行もの PostgreSQL テーブルをパーティション分割した Evil Martians 社。

  1. 親テーブルをクローン。
  2. 子テーブル + 親テーブルの PK をマッピングするビュー作成。
  3. 子テーブルを作成・更新するストアドプロシージャ作成。
  4. ストアドプロシージャを呼ぶトリガーをビューに張る。
  5. ActiveRecord モデルがビューを見るように設定。
  6. 既存データはビューに INSERT することで移行。

Turn Rows Into Columns With The Array#transpose Method

Array#transpose いろいろ。

  • 二次元配列で行と列を入れ替えてくれる。
  • 三目並べゲームの勝利判定ロジックを例に挙げた。

Upgrading a Rails App from 3.2 to 4.0

Rails 3.2 アプリを 4.0 にアップグレードするための豆知識。移行してない人がまだまだいるから。

  • Ruby 1.8.7 を使っていれば、1.9.3 にアップグレード。
  • rails4_upgrade gem を Gemfile に追加して、アップグレードの必要な gem を特定。
  • rails:update Rake タスクで不要な設定・モンキーパッチを削除。
  • RailsDiff で予想された差分を確認。
  • activerecord-deprecated_finders gem で .find_by_hoge メソッドを洗い出し・撲滅。
  • scope は全部 lambda 表記に。
  • protected_attributes 撲滅。あるいは protected_attributes gem 導入。Strong Parameters に移行することがベスト。
  • ActiveRecord::Observer 撲滅。あるいは rails-observers gem 導入。wisper gem または Rails Concerns に移行するのがベスト。
  • ActiveResourceactive_resource gem に移行。
  • caches_page caches_actionactionpack-action_caching gem に移行。
  • Test::Unittest-unit gem に移行。
  • match 式 route は HTTP メソッド要指定。
  • プラグインを使っていれば gem に移行。

Code

Arbolito: A Minimalist Currency Conversion Library

Alpha Vantage API を叩く両替 gem。Alpha Vantage 以外でも拡張可能。キャッシュ期限設定可能。他 gem への依存が一切ない。

wsdirector: A Command Line Tool for Testing WebSockets

ActionCable など WebSocket サーバテスト用 CLI ツール gem。データ送受信スクリプトYAML で定義してから wsdirector コマンドで実行。ApplicationCable::Channel単体テストと思えば良さそう。(RSpec・MiniTest・Test::Unit とは別物)