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

週刊Railsウォッチ: Ruby30周年記念イベント、ActiveRecord APIクイズほか(20230221前編)

こんにちは、hachi8833です。今週土曜日2/25の13:30からプログラミング言語Ruby30周年記念イベントがストリーム配信で開催されます🎉

参考: プログラミング言語Ruby30周年記念イベントにkoicとima1zumiがLT登壇します - ESM アジャイル事業部 開発者ブログ

週刊Railsウォッチについて

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

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

お知らせ: 来週は週刊Railsウォッチに代えて通常記事を公開します🙇

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

🔗 railsタスク説明文の動詞の表記を統一

共通のrailsコマンドや一部の拡張コマンドのdescriptionでは、動詞を不定詞(infinitive)の形で用いている("Generates ..."や"Starts ..."や"Runs ..."ではなく、"Generate ..."や"Start ..."や"Run ...")。
この変更では一貫性のため、それ以外のタスクでも動詞を不定詞の形で揃えた。
同PRより


つっつきボイス:「infinitive formは英語の"不定詞"で、動詞の原型になります」「タスクのヘルプに表示される冒頭の動詞の表記ゆれを統一したんですね↓」「気にし始めると気になりそう」「こういう修正が積み重なって品質が向上する👍」「説明文が"Creates"みたいに三人称単数現在形で開始すると、直前のrails db:createとかが事実上の主語になるという感じなのかな」「"Create"みたいに不定詞で始まると、事実上の主語の単数複数に影響されない説明文になるのかも🤔」

# activerecord/lib/active_record/railties/databases.rake#L44
- desc "Creates the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to create all databases in the config). Without RAILS_ENV or when RAILS_ENV is development, it defaults to creating the development and test databases, except when DATABASE_URL is present."
+ desc "Create the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to create all databases in the config). Without RAILS_ENV or when RAILS_ENV is development, it defaults to creating the development and test databases, except when DATABASE_URL is present."
# guides/source/active_record_multiple_databases.md#L168
$ bin/rails -T
-rails db:create                          # Creates the database from DATABASE_URL or config/database.yml for the ...
+rails db:create                          # Create the database from DATABASE_URL or config/database.yml for the ...

参考: 不定詞の「不定」とは何なのか | 英語イメージリンク

🔗 クエリのエンコードが壊れている場合のActiveRecord::QueryLogsの処理を改善

クエリをビルドするときにバイナリデータを含めるためにBLOBフィールドを使うことはよくある。文字列をASCII-8BITで注意深くエンコードしておかないと、一般にUTF-8でエンコードされてしまい、QueryLogsがそこで失敗してしまうことがある。この修正で、ActiveRecord::QueryLogsは、クエリのエンコードが適切かどうかに依存しなくなった。
Jean Boussier
同PRより


つっつきボイス:「クエリに'\xFF'みたいなUTF-8エンコードでない文字列があるとQueryLogsでログがおかしくなる可能性があった↓: たしかにBLOB(Binary Large OBject)を扱うときだとありそう」

# activerecord/test/cases/query_logs_test.rb#219
  # Postgres does validate the query encoding. Other adapters don't care.
  unless current_adapter?(:PostgreSQLAdapter)
    def test_invalid_encoding_query
      ActiveRecord::QueryLogs.tags = [ :application ]
      assert_nothing_raised do
        ActiveRecord::Base.connection.execute "select 1 as '\xFF'"
      end
    end
  end

参考: Rails API ActiveRecord::QueryLogs
参考: バイナリ・ラージ・オブジェクト - Wikipedia

🔗 bin/rails testの挙動を追加修正

#46664のフォローアップ。
#46664では、引数なしのbin/rails testbin/rails test:allbin/rails test:systemは、test:prepareタスクを実行するようになった。
しかし、引数ありのbin/rails test(例: bin/rails test --seed 1234)やその他のtest:*コマンド(例: bin/rails test:models)はそうなっていなかった。

このコミットは、bin/rails testに正確なテストファイルがパス引数(例: bin/rails test path/to/test.rb)や名前引数(例: bin/rails test -n test_foo)が指定されていない場合は常にtest:prepareを実行するように変更する。

このコミットは同時に、どのファイルを読み込むか、およびtest:prepareを実行するかどうかに関連するすべてのロジックをTestCommandクラスに含める形でリファクタリングする。
同PRより


つっつきボイス:「bin/rails testの改修は先週見たような気がすると思ったら#46664の続きだった(ウォッチ20230207)」「bin/rails test:modelsとかのケースが前回見落とされていたのを修正・リファクタリングしたんですね」「元の改修が長文でややこしいので、詳しくは先週のウォッチ20230207から読むのがよさそう」

🔗 AbstractControllerMissingHelperErrorを非推奨化

動機/背景
このMissingHelperErrorは、かつてLoadErrorのラッパーで、require_dependencyが使われていた時代にコントローラでヘルパーを読み込んだときにこれがraiseされていた。
Zeitwerkはrequire_dependencyを使わないので、このエラーの唯一の利用場所は5b28a0eで削除されていた。
同PRより


つっつきボイス:「require_dependencyはZeitwerkのおかげでRails 7から完全に不要になってましたよね」「Rails 7からClassicモードは使えなくなりましたね」「require_dependencyが使われなくなっているので、そのためにMissingHelperErrorが使われることもない: これはなくしてもいいヤツ👍」「いつものようにdeprecationの手続きを踏んでいるけど、すぐ消しても問題ないかも」

# actionpack/lib/abstract_controller/helpers.rb#L26
-   class MissingHelperError < LoadError
+   class DeprecatedMissingHelperError < LoadError
      def initialize(error, path)
        @error = error
        @path  = "helpers/#{path}.rb"
        set_backtrace error.backtrace
        if /^#{path}(\.rb)?$/.match?(error.path)
          super("Missing helper file helpers/%s.rb" % path)
        else
          raise error
        end
      end
    end
+   deprecate_constant "MissingHelperError", "AbstractController::Helpers::DeprecatedMissingHelperError",
+     message: "AbstractController::Helpers::MissingHelperError has been deprecated. If a Helper is not present, a NameError will be raised instead.",
+     deprecator: AbstractController.deprecator

参考: Rails API require_dependency -- ActiveSupport::Dependencies::RequireDependency -- 現在非推奨
参考: Rails API: AbstractController::Helpers::MissingHelperError
参考: 定数の自動読み込みと再読み込み (Zeitwerk) - Railsガイド

🔗 必要な場所ではRack固有のヘッダーを使うよう修正

Rack 3のレスポンスヘッダーは、キーが小文字のミュータブルなハッシュでなければならない。Rackは、この要件に準拠していない既存システムとの互換性を保つためにRack::Headersを提供している。Rack 2ではRack::Utils::HeaderHashを、Rack 3ではRack::Headersを使うのが望ましい。

ヘッダーのキーがnilであることをテストするいくつかのレスポンステストについては無効とみなされており、Rack::Headersで失敗するため削除した。
同PRより

rack/rack - GitHub


つっつきボイス:「Rack 3とRack 2の互換性に関する修正か」「そういえばRack 3からはレスポンスヘッダーをイミュータブルにしてはいけないんだった↓」「そうそう、レスポンスヘッダーのキー名も小文字のみになるなど仕様が変わってましたね: Rack 3はアプリケーションによってはbreaking changeになるかも」

Rack 2-> Rack 3アップグレードガイド(翻訳)

なおRackのアップグレードガイドは現在作業中です。現時点のRails 7.1.0.alphaではRack 3.0.4.1が使われますが、Rails 7ではRack 2.2.6.2が使われます。

🔗 Railsサブコマンドのヘルプ表示を改善


つっつきボイス:「プルリク数は多いですが、thor gemを使ってbin/railsのサブコマンドのヘルプ表示をさまざまに改善したそうです↓」「サブコマンドを間違えたときの"Did you mean?"も効くようになったんですね👍」

# 同PRより: 改修前
$ bin/rails secrets --help
Usage:
  bin/rails secrets

=== ** DEPRECATED **

Rails 5.2 has introduced a new `credentials` API that replaces Rails secrets.
...

$ bin/rails secrets:setup --help
Usage:
  bin/rails secrets

=== ** DEPRECATED **

Rails 5.2 has introduced a new `credentials` API that replaces Rails secrets.
...

$ bin/rails secrets:edit --help
Usage:
  bin/rails secrets

=== ** DEPRECATED **

Rails 5.2 has introduced a new `credentials` API that replaces Rails secrets.
...
# 同PRより: 改修後
$ bin/rails secrets --help
Commands:
  bin/rails secrets:edit            # Open the secrets in `$EDITOR` for editing
  bin/rails secrets:help [COMMAND]  # Describe available commands or one specific command
  bin/rails secrets:setup           # Deprecated in favor of credentials -- run `bin/rails credentials:help`
  bin/rails secrets:show            # Show the decrypted secrets

=== ** DEPRECATED **

Rails 5.2 has introduced a new `credentials` API that replaces Rails secrets.
...

$ bin/rails secrets:setup --help # OR bin/rails secrets:help setup
Usage:
  bin/rails secrets:setup

Deprecated in favor of credentials -- run `bin/rails credentials:help`

$ bin/rails secrets:edit --help # OR bin/rails secrets:edit setup
Usage:
  bin/rails secrets:edit

Open the secrets in `$EDITOR` for editing

「thor gemはコマンドラインインターフェイスのツールキットか」「Thor(トール、ソー)は北欧神話の神の名前でしたっけ」「これと似た名前の別のgemだかツールがあった気がする、たしか自分のPC環境を調べるものだったと思うけど、見当たらない」「思い出せない...」

rails/thor - GitHub

参考: トール - Wikipedia

🔗Rails

🔗 Active Record APIクイズ(Ruby Weeklyより)


つっつきボイス:「VectorLogicという会社の技術ブログにActive Record APIのクイズが10問掲載されています」「Active Record APIのテストの話かと思ったらtest yourselfだった」「お、どれどれ」(一同しばらくつっつく)


同記事より

「慣れ親しんでいるActive Recordだけど、制限時間があると難しい」「よく見ると問題によっては複数回答可能なのものもあったか、しまった」「正しいコードをプルダウンから選ぶ問題もあった」「制限時間も問題によって少しずつ違うけど、1分って短い」「焦りますよね」「このブログには他にもクイズ記事があるみたい」「楽しいので一度やってみるといいと思います👍」

後で探しました↓

参考: Test Yourself on Ruby Object Model
参考: Test Yourself on Operator Precedence in Ruby

🔗 その他Rails


つっつきボイス:「Railsガイドを更新翻訳していて、本家の現在のアセットパイプラインガイドの記述がRails 6.x時代の内容であることに気づいて調べているうちに上のプルリクを見つけました」「本家のアセットパイプラインガイドをRails 7のimportmaps-railsやturbo-railsなどに合わせて大幅に更新するプルリクですね: 更新されたらチェックしてみよう👍」

Rails 7: importmap-rails gem README(翻訳)

🔗 Hanami

🔗 AppSignalでHanamiを監視する


つっつきボイス:「AppSignalの技術記事です」「AppSignalはいわゆるAPM(アプリケーションパフォーマンス監視)サービスを手がけている会社ですね」

参考: Application Monitoring for Ruby on Rails, Elixir & Node.js | AppSignal APM
参考: Application performance management - Wikipedia

# 同記事より
require "hanami/boot"
require "appsignal/integrations/hanami" # Add this line

run Hanami.app
# 同記事より
# config/appsignal.yml
production:
  active: true
  push_api_key: "1234-1234-1234"
  name: "My app"

「記事によると、今後はdry-rbシリーズのdry-monitorでHanamiのAppSignal統合を拡張したいそうです」

dry-rb/dry-monitor - GitHub

参考: dry-rb - Home


前編は以上です。

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

週刊Railsウォッチ: Bundler 2.4リリース、RubyKaigi 2023参加募集開始ほか(20230215後編)

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

Rails公式ニュース

Ruby Weekly


CONTACT

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