Rails 6のB面に隠れている地味にうれしい機能たち(翻訳)

### 概要 原著者の許諾を得て翻訳・公開いたします。 英語記事: Rails 6: B-Sides and Rarities — Martian Chronicles, Evil Martians’ team blog 当記事へのバックリンクを貼っていただきました🙇 原文公開日: 2019/04/29 著者: Vladimir Dementyev — Railsコントリビュータ、Evil Martiansメンバー サイト: Evil Martians — NY/サンフランシスコ/モスクワに拠点を構え、Rails・モバイル・インフラ・ビッグデータ分析などを手がける米国の開発企業です。GitHubでのgem公開やgemのスポンサーシップ、RubyKaigi 2019やRailsConf 2019の登壇など活発に活動しています。 evilmartians.comより Rails 6のB面に隠れている地味にうれしい機能たち(翻訳) 概要: 次回のメジャーアップグレードの中から、運用実績のある成熟したアプリケーションでも使いたくなるような、あまり知られていない機能を発掘したいと思います。昔の音楽に例えれば、「ヒットチャート上位」に顔を出すような売れ線の機能ではなく、LPレコードのB面やレアコレクションに隠れている名曲のような、新しいリリースの「地味だけど絶妙に役立つ」機能に目を向けてみたいと思います。 Rails 6で最も喧伝されているAction MailboxとAction Textのような機能につい目を奪われがちですが、アップグレードするだけで利用できるWYSIWYGテキストエディタが、ある程度の期間運用されている現実のRailsアプリで今すぐに重宝するとは考えにくいでしょう。 一方、マルチデータベースのサポートやパラレルテストのような、それほど前面に出ていない機能がただちに生産性向上に役立つようなこともあります。Rails 6には、そうした一見の価値のある機能が目白押しです。 私は数年前にAction Cableの改良に携わって以来、Railsフレームワークの開発を追いかけており、無数のプルリクに目を通しています。Rails 6 RC版リリースの数か月前には、既にある中規模クラスのRails 4アプリをRails 6向けに書き直す権限を与えられました。 私はAnyCableを手がけていることもあって、なんとかCableのたぐいは私の専門分野と言えます。 私は熱狂的な音楽ファンでもあるので、Railsという大規模フレームワークのリリースを目撃するのは、さながら(音楽の)レコード発売日に居合わせるような心持ちです。ヘビロテされる大ヒット曲もあれば、B面に埋もれたままになったり、ファンが発掘してレア物としてありがたがる曲もあります。 本記事では、このたびリリースされるRailsの舞台裏で息を潜めているgemを拾い上げてみたいと思います。新しいgemもあれば、数年の時を耐え忍んでRails 6にマージされたgemもありますし、プルリク一発のコードもあれば、Rails 6.xまでおあずけのgemもあります。 Action Cableのテスト Rails 5のメジャーな機能であるAction Cableは、WebSocketsをすぐに利用でき、JavaScriptライブラリも同梱されていました。Action CableはRails wayの「設定より規約」に沿っていて構文も親しみやすいのですが、テスト駆動アプローチのサポートが抜け落ちていました。つまり、チャンネルのテストを書くための公式な方法が提供されていなかったのです。 Rails 6では、Action CableのJavaScript部分がついにCoffeeScriptとおさらばし、#34177でES6に書き直されました。 ある日、私は#23211を再オープンして修正する機会がありました。このプルリクはRails 5に取り込まれることになっていたのですが、最終的な曲目からは漏れてしまいました。その代り、シングル盤レコード(つまりaction-cable-testing gemのことです)をリリースし、3年越しでついに#33659でRails 6にマージされたのです。 というわけで、新しいRails 6プロジェクトで(–skip-action-cableを付けずに)rails newを実行すれば、app/channelsフォルダに加えてtest/channelsフォルダも作成されるようになりました。 サンプルではRSpecが使われています。Action Cableの統合はaction-cable-testing gemで実装されていますが、RSpec 4でマージされる予定です(#2113)。 さて、Action Cableではどこをテストすればよいのでしょうか?現実のアプリで使われている事例を見てみましょう。 Action Cableの接続周りであれば、次のように認証に関連するロジックをテストしたいでしょう。 # spec/channels/application_cable/connection_spec.rb require “rails_helper” # `type: :channel`でAction Cableテスティングヘルパーを追加する # 現時点ではaction-testing-cable gemを使うが、RSpec 4に同梱されるはず RSpec.describe ApplicationCable::Connection, type: :channel do let(:user) { create(:user) } it “cookieでの接続に成功する” do # “virtual”リクエストcookieをセット cookies.signed[:user] = user.id # `connect`メソッドはサーバーへのwebsocketクライアント接続を表す connect “/websocket” # idが正しく設定されたことをチェックできるようになった expect(connection.current_user).to eq user end it “cookieなしの接続は拒否する” do # cookieが渡されない場合は接続を拒否することをテストする expect { connect “/websocket” }.to have_rejected_connection end it “存在しないユーザーからの接続は拒否する” do cookies.signed[:user] = -1 expect { connect “/websocket” }.to have_rejected_connection end end その他のAction Cableプリミティブである「チャネル」のテストもさらに興味深いものになりました。チャネルはWebSocketのコントローラとみなすことができます。 以下のテストで使っているPresenceChannelクラスは、実際のアプリでもさまざまなページに渡るユーザーのアクティビティを正確にトラッキングするのに使われています。#subscribe向けに以下のテストシナリオがあります。 ユーザーがそのチャンネルに接続するときは、プレゼンストラッキングシステムに登録されていなければならない ユーザーがそのチャンネルに接続するときは、対応するストリームでサブスクライブされなければならない(通知を受け取るため) ユーザーがそのチャンネルに接続するときは、「ユーザーが参加しました」という通知をストリームに送信しなければならない 真新しいAction Cableテストユーティリティを用いて、次のテストを書きます。 require “rails_helper” RSpec.describe PresenceChannel, type: :channel do # `let_it_be`ヘルパーは`test-prof` gemが提供 let_it_be(:projectschool) { create(:project) } let_it_be(:user) { create(:user, project: project) } before do # `stub_connection`は、渡されたidで # Connectionインスタンスを初期化する stub_connection current_user: user … Continue reading Rails 6のB面に隠れている地味にうれしい機能たち(翻訳)