Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ: AssumeSSLミドルウェア追加、Fly.ioとRails 7.1のDocker対応ほか(20230214前編)

こんにちは、hachi8833です。

週刊Railsウォッチについて

  • 各記事冒頭には🔗でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • お気づきの点がありましたら@hachi8833までメンションをいただければ確認・対応いたします🙏

TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)

🔗Rails: 先週の改修(Rails公式ニュースより)

🔗 ActionDispatch::AssumeSSLミドルウェアが追加された

これは、すべてのリクエストがSSLで転送されているとアプリケーションに信じ込ませる。
一般に、SSLを終端するロードバランサをプロキシとして利用しているとき、転送されるリクエストはアプリケーションからはHTTPSではなくHTTPで通信しているかのように見えるが、こうした場合に有用。
このミドルウェアは、プロキシが既にSSLを終端していてリクエストが本当にHTTPSであるとサーバーに仮定させる。
DHH
同Changelogより


つっつきボイス:「DHHによるプルリクですが、これはどういう改修でしょうか?」「リクエストにX-Forwarded-Forなどがつかないプロキシ環境でもRails内部でSSLだと認識させるRackミドルウェアを追加したということのようですね」「なるほど、さすがにデフォルトではオフみたい」「Rails側でSSLをセットアップしなくても使えるようになるので、CIなどでこういう機能が欲しくなることはありますね👍」

NGINXなどのSSL終端リバースプロキシは、HTTPヘッダーを用いて転送情報を含めることが可能。現在のスタックにネットワークロードバランサー経由のSSL終端が含まれる場合はそうならない。config.assume_sslを使うことで対処できるようになる。
同PRより

参考: X-Forwarded-Proto - HTTP | MDN

「追加されたRackミドルウェアを見ると、強制的にHTTPSを設定している↓」「ガチ強制じゃないですか」「やっていることは一目瞭然で理解できますね」

# actionpack/lib/action_dispatch/middleware/assume_ssl.rb#L7
module ActionDispatch
  class AssumeSSL
    def initialize(app)
      @app = app
    end

    def call(env)
      env["HTTPS"] = "on"
      env["HTTP_X_FORWARDED_PORT"] = 443
      env["HTTP_X_FORWARDED_PROTO"] = "https"
      env["rack.url_scheme"] = "https"

      @app.call(env)
    end
  end
end

🔗 config/environments/production.rbでRAILS_LOG_LEVEL環境変数に応じてログレベルを設定するようになった

コードを変更することなく、必要に応じて手軽にデバッグモードに切り替えられるようにした。
同PRより


つっつきボイス:「従来のproduction.rbではconfig.log_level = :infoで固定されていたのが、RAILS_LOG_LEVEL環境変数でログレベルを設定できる形でproduction.rbが生成されるようになったんですね↓」「production.rbを書き換えずにログレベルを変更できるようになったのは嬉しい」「独自に設定することも可能ですけど、環境変数名がアプリごとにバラつきやすくなるので、RAILS_LOG_LEVELという環境変数名が公式に決まるのはありがたい👍」「ですね」

# railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt#L70
- # Include generic and useful information about system operation, but avoid logging too much
- # information to avoid inadvertent exposure of personally identifiable information (PII).
- config.log_level = :info
+ # Info include generic and useful information about system operation, but avoids logging too much
+ # information to avoid inadvertent exposure of personally identifiable information (PII). Use "debug"
+ # for everything.
+ config.log_level = ENV.fetch("RAILS_LOG_LEVEL") { "info" }

参考: §3.1.25 config-log-level -- Rails アプリケーションを設定する - Railsガイド

🔗 config.i18n.raise_on_missing_translations = trueをビューやコントローラ以外でも効くように変更

動機/背景
このプルリクを作成した理由は、現在のconfig.i18n.raise_on_missing_translations = truet('missing.key')をビューかコントローラで呼び出した場合にしか効かないため。しかし#47057で指摘されているように、このコンフィグ名はキーを認識できなければ常にraiseすることを示唆している。
詳細
このプルリクは、config.i18n.raise_on_missing_translations == trueの場合にI18n.exception_handlerを実装する。任意の例外をraiseするため、デフォルトの振る舞いを少しいじった。
ビューやコントローラにおけるtメソッドの既存のraiseの振る舞いは変更なし。
ついでにi18nガイドも更新してこの振る舞いを反映し、アップグレードガイドにも追記した。
追加情報
修正対象: #47057
このプルリクがマージされるなら、#45361のマージはたぶん不要。
同PRより


つっつきボイス:「config.i18n.raise_on_missing_translations = trueオプションの挙動が変更されて、tメソッド(translateのエイリアス)で訳文のキーが見つからない場合は常にエラーになるようになったんですね」「ちなみにこういうオプションは、E2E(エンドツーエンド)テストなどで訳文漏れを発見したいときに便利でしょうね」

参考: Rails API translate -- AbstractController::Translation

🔗 ActiveRecord::Relation#explainにオプションを渡せるようになった

サポートされているデータベースとアダプタ(現時点ではPostgreSQLとMySQL)で、explainにさらに詳細なクエリプラン分析を渡せるようになった。

Customer.where(id: 1).joins(:orders).explain(:analyze, :verbose)

Reid Lynch
同Changelogより


つっつきボイス:「Active RecordのRelation#explainって使ったことなかったかも」「これってSQLのクエリプランを表示するんですよね?」「:analyze:verboseオプションを指定できるので間違いなくそうですね」「いつもMySQLのコンソールでやってるので、Active Recordにこんな機能があったとは気づきませんでした」「EXPLAINはMySQLとPostgreSQLで構文が微妙に違ったりしますね」「RailsのexplainはMySQLとPostgreSQLとSQLite3で使えるんですって」

参考: Rails API explain -- ActiveRecord::Relation

参考: クエリ実行計画 - Wikipedia

🔗 Action Textが依存するTrixがバージョンアップされた

バンドルされているTrixのバージョンを1.3.1から2.0.4にアップデートした。
Sean Doyle
同Changelogより


つっつきボイス:「Action Textで使われているTrixエディタがメジャーアップデートされたそうです」

参考: Update Action Text's Trix dependency by seanpdoyle · Pull Request #46447 · rails/rails -- #46447からインデント修正を除いた更新差分

参考: Action Text の概要 - Railsガイド
参考: Trix: A rich text editor for everyday writing

🔗Rails

🔗 Rails 7.1に備えるFly.io


つっつきボイス:「先週のDocker関連の改修(ウォッチ20230207)でDHHが引用していたFly.ioの書き込みです」「Fly.ioはHerokuのようなPaaSですね」

参考: Deploy app servers close to your users · Fly

「DHHはFly.ioが生成しているDockerfileをRails 7.1で参考にするつもりのようです」「マルチステージビルドとかも取り入れているんですね」「Dockerfile、特にマルチステージビルドのようなものはその道に強い職人が作るのがいいと思う」「ほんと難しいですよね」「Fly.ioはメモリ不足時のスワップファイル対応などもやっていたりして、かなりちゃんとしたホスティングをやっていそう」

こんにちは、Sam
デフォルトのDockerファイルをできるだけベストな形に持っていくためにこれを役立てられればと思います。さしあたって以下のあたりをチェックしたいと思います。

  • Nodeを使う場合のマルチステージビルド(ただしデフォルトのimport mapパスはそのままにしたい)
  • デフォルトでjemallocを利用したい(セグメンテーションフォールトのリスクは冒せないので、背後のディストロで絶対的に保証できるのであれば)
  • debian slimイメージ周り。イメージサイズより互換性を重視したいので、すべての主要gem(および有名なマイナーgem)の依存性をslimイメージにおいて満たさなければならない。
  • スワップファイル周り(メモリ不足で死ぬよりいい)

質問

  • そちらではVoltaで必要なnode/npmバージョンをどこでトラッキングしているか?
  • そちらの標準タスクで使われているRakefileを見せてもらってもよいか?(リリース版のも可能か?)
  • 依存関係のセットアップはdocker-composeでやっているか、それとも他の方法か?
    Preparations for Rails 7.1 - General - Fly.ioのDHHコメントより

🔗 rails-graphql: Railsアプリ向けの新しいGraphQLライブラリ

virtualshield/rails-graphql - GitHub


つっつきボイス:「Webチームのメンバーがはてブで見つけたものです」「既に使われているgraphql-ruby↓より後から出したということはそれなりのアドバンテージはあるのかも」

rmosolgo/graphql-ruby - GitHub

「rails-graphqlリポジトリのgemspecを見てみると、graphql-ruby gemには依存していないので自前の実装なんですね」「今のバージョンはv1.0.0 RC1か」

「rails-graphqlはRailsのActive RecordやAction Cableと密接に連携するとありますね: graphql-rubyは基本的にアクションの中でスキーマを読み込んで処理する形なのでAction Cable連携とかはそのままでは難しそうだから、その辺りがよりRailsに特化しているということなのかもしれませんね」「これ使ってみようかな」

🔗 rails7-startkit: Rails 7をDockerで開始するキット(RubyFlowより)

the-teacher/rails7-startkit - GitHub


つっつきボイス:「Rails 7アプリを動かすキットをDockerで作ったようです」「RedisにSidekiqにElasticsearch、他にもいろいろ積まれている」「随分盛りだくさんですね」「業務ですぐ使うかどうかは別にして、Rails 7をさっと試してみたいときにいいかも」

🔗 その他Rails


つっつきボイス:「thoughtbotがまとめた世界の地域ごとのRuby/Rails関連イベント団体です」「掲載されている地域が赤色で表示されているみたい」「日本で掲載されているのは今のところTokyo Rails Meetupだけなんですね」


前編は以上です。

バックナンバー(2023年度第1四半期)

週刊Railsウォッチ: ShopifyのYJIT記事、RubyGemsのgem execコマンドほか(20230202後編)

ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。

Rails公式ニュース

Ruby Weekly

RubyFlow

160928_1638_XvIP4h


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。