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

週刊Railsウォッチ: dartsass-railsがリリース、webpack-mergeツール、Rubyが29歳にほか(20220228前編)

こんにちは、hachi8833です。つっつきの日がお誕生日でした🎉

週刊Railsウォッチについて

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

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

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

公式更新情報で1件見逃していたものがあったので、そこから見繕いました。

🔗 Objectinstance_valuesを最適化

#44257のフォローアップ。
#44213のレビューでas_jsonのパフォーマンスを調べてみた。Object#instance_variable_namesではシンプルな最適化がいくつか行えた。
Array#to_hは本質的にHash::[]よりかなり高速(インターフェイスが厳密で正しいサイズのハッシュを事前にアロケーションできる)。
また、Hash#[]で文字列が重複しないよう早い段階でfreezeさせる。
#44258より


つっつきボイス:「instance_variable_namesの方は少し前にも見た覚えがありますね(ウォッチ20220131)」

# activesupport/lib/active_support/core_ext/object/instance_variables.rb#L14
  def instance_values
-   Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
+   instance_variables.to_h do |ivar|
+     [ivar[1..-1].freeze, instance_variable_get(ivar)]
    end
  end

🔗 ActiveModel::Name#humanhuman_attribute_nameを最適化

ActiveModel::Name#humanのアロケーションを削減して、訳文が定義されていない場合のパフォーマンスを2倍程度改善するリファクタリング。
#44299より


つっつきボイス:「humanhuman_attribute_nameはI18n定義を使って読みやすく変換するヤツですね」「お〜だいぶ速くなったらしい」

# https://api.rubyonrails.org/classes/ActiveModel/Name.html#method-i-humanより
BlogPost.model_name.human # => "Blog post"
# https://api.rubyonrails.org/classes/ActiveModel/Translation.html#method-i-human_attribute_nameより
Person.human_attribute_name("first_name") # => "First name"

🔗 Active RecordのConnectionPoolをFiberセーフにした

Active RecordのConnectionPoolをFiberセーフにする。IsolationExecutionStateに少し手を加えてプール内のさまざまなキャッシュキーメソッドを実装し、それらをThread.currentから切り離せるようにする必要があった。
まだテストは追加していないが、ローカルで動かしてみたところうまくいっている様子。
その他の情報
Active RecordのConnectionPoolをFiberセーフにすることが望ましい理由については#42271を参照。
このアプローチでは、Sidekiq内のActive RecordもFiberセーフになる。app.reloader.wrapでリクエストやジョブなどをラップする他のgemも同様。
同PRより


つっつきボイス:「お〜、ConnectionPoolがFiberセーフになった」「むしろ今までそうなってなかったとは」

ActiveSupport::IsolatedExecutionState.isolation_level:fiberに設定されると、コネクションプールが同じThreadから複数のFiberをチェックアウトすることをサポートするようになった。
Alex Matchneer
同Changelogより

参考: class Fiber (Ruby 3.1 リファレンスマニュアル)

isolation_levelでFiberセーフにするかどうかを切り替えられるのが面白い: falconあたりを使うときにこのスイッチをオンにするとよさそうだけど、#42271を見るとやはりfalconが取り上げられていますね↓」「ほんとだ」「falconはまだ使ったことはありませんが、Fiberスケジューラを利用しているといえばfalconぐらいしか思いつかない」

socketry/falcon - GitHub

🔗 ガイド改修

逆関連付けが具体的に何をするのか戸惑ったことを思い出す。このガイドは役に立ったが、いくつかのユースケースが抜けている。それらをまとめてコード例とともにドキュメント化することで、Railsが逆関連付けを推論できないときに:inverse_ofを設定する理由が理解しやすくなることを期待する。
このコミットではドキュメントに以下の改修を行う。

  • Authorオブジェクトがすべて同じで、追加のクエリが実行されないことを明示する例を追加。
  • データ不整合の防止に関する例は維持(ただし1文字変数は置き換えた)。
  • オートセーブの例を追加(他の場所で明示的にドキュメント化されているかどうかはわからない)。
  • バリデーションの例を追加し、関連するバリデーションガイドへリンクした。

:inverse_ofセクションがよりクリアになるよう、:inverse_ofセクションから双方向関連付けセクションへのリンクも追加した。
同PRより


つっつきボイス:「inverse_ofのドキュメントが改善された」「そういえばinverse_ofの部分はわかりにくかったかも」「Railsのバージョンによって少しずつ変わっていたりするのでややこしい: 外部キー周りの解説なども増えたのはよさそう👍」「ところでabsenceバリデータというのもあるんですね↓、presenceバリデータは使ってますが」

# guides/source/association_basics.md#L803
+* Validate the [presence](active_record_validations.html#presence) and
+ [absence](active_record_validations.html#absence) of associations in more
+ cases
+
+   ```irb
+   irb> book = Book.new
+   irb> book.valid?
+   => false
+   irb> book.errors.full_messages
+   => ["Author must exist"]
+   irb> author = Author.new
+   irb> book = author.books.new
+   irb> book.valid?
+   => true
+   ```

参考: §2.10 presence -- Active Record バリデーション - Railsガイド
参考: §2.11 absence -- Active Record バリデーション - Railsガイド

🔗Rails

🔗 Dart Sass for Rails(Rails公式ニュースより)

rails/dartsass-rails - GitHub


つっつきボイス:「Rails公式更新情報のエントリをここに置きました」「Dart Sass↓のバイナリ版がdartsass-railsに入ったので、DartをインストールしなくてもSassが使えるようになったんですね」

sass/dart-sass - GitHub

「そういえばこの間記事にしたtailwindcss-railsもバイナリ版のツールを使うところがちょっと似ていますね↓」

Rails 7: importmap-rails + tailwindcss-railsでnode.jsが不要な理由

「見たところ他のプラットフォームでは普通にバイナリを使うけど、Windowsだけ別途dart.exeが必要なのね↓」「あら、惜しい」「さらにLinuxとMacにはArm版バイナリはあるけどWindows版にはない」

# dartsass-rails/exe/mingw32/sass.batより
@echo off
REM This script drives the standalone dart-sass package, which bundles together a
REM Dart executable and a snapshot of dart-sass.

set SCRIPTPATH=%~dp0
set arguments=%*
"%SCRIPTPATH%\src\dart.exe" "%SCRIPTPATH%\src\sass.snapshot" %arguments%

「あれ、WindowsってそもそもArmで動くんですか?」「動きますよ、まだプレビューですが、Arm版Windowsを動かしている人たちをちらほら見かけます」「Arm版Windowsは話に聞いたことしかありませんね〜」「Armといえば、Windows RTが動くArm版タブレットSurfaceというのもありました、全然盛り上がりませんでしたが😆」

参考: “Arm版Windowsノート”のスゴさ知ってますか?スマホの手軽さとPCのパワーが同居する「HP Elite Folio」 - PC Watch[Sponsored]
参考: Microsoft Windows RT - Wikipedia

🔗 webpack-merge: webpackのコンフィグをマージするツール

survivejs/webpack-merge - GitHub


つっつきボイス:「お〜、webpackの複数のコンフィグをマージできるんですね↓: 移行中に設定を少しずつ更新して様子を見ながら設定の差分を作ったりするのに便利そう👍」

// 同リポジトリより
const { merge } = require('webpack-merge');

// Default API
const output = merge(object1, object2, object3, ...);

// You can pass an array of objects directly.
// This works with all available functions.
const output = merge([object1, object2, object3]);

// Keys matching to the right take precedence:
const output = merge(
  { fruit: "apple", color: "red" },
  { fruit: "strawberries" }
);
console.log(output);
// { color: "red", fruit: "strawberries"}

「ところでこのwebpack-mergeは以下のWebpacker->Shackpacker移行ガイド↓を翻訳しているときに知ったんですが、まだ少しタイポとかが残っているようなので、落ち着いたら翻訳を再開しようかなと思っています」「こうやってレビューされることでドキュメントは良くなっていきますよね☺️」

参考: shakapacker/v6_upgrade.md at master · shakacode/shakapacker

その後ドキュメントにいくつか修正が入り、自分が投げたプルリクもマージされました↓。

参考: docs: improve v6 upgrade guide by G-Rath · Pull Request #71 · shakacode/shakapacker
参考: Fix typos for v6_upgrade.md by hachi8833 · Pull Request #72 · shakacode/shakapacker

🔗 Railsコミュニティアンケート2022年度版(Ruby Weeklyより)


つっつきボイス:「これまでもウォッチで何度か取り上げた、rails-hosting.comによるRailsコミュニティ向けのアンケートの募集が始まったそうです」「2年に一度やっている感じかな」「以前回答したのを思い出した」「アンケートに答えながら話してみようかなと思ってやってみたけど、エントリー数が思ったより多かった...」

なお、以下は2020年度の結果です↓。

参考: 2020 Ruby on Rails Community Survey Results | 2020 Ruby on Rails Community Survey Results

🔗 JavaScript SPAからRailsでやることにした話(Ruby Weeklyより)


つっつきボイス:「Reactも使うけど、Railsの方が考えることが少なくて助かるという感じの趣旨でした」「どんなアプリを作るかにもよると思いますけど、JavaScriptはフレームワークもツールも豊富でユーザーも多い分、どれとどれをどう組み合わせるかなど決めないといけないことが多いという面はあるでしょうね」「慣れてくればいいと思うんですけど、最初が大変そうですね...」

🔗 その他Rails

つっつきボイス:「1つ目はDHHブログのPropshaft記事です」「これまでDHHが述べてきた路線を踏襲している感じですね」

記事の末尾によると、Rails 8まではPropshaftをデフォルトとして検討することはなさそうです↓。

This isn't a quick migration, and there's no prospect of considering Propshaft as the new default until Rails 8.
Introducing Propshaftより

「2つ目は今日社内で話しましたが、nokogiriが依存しているlibxml2やlibxsltで脆弱性が発生したのでアップデートが出たことをbundler-auditくんが知らせてくれました↓」「そうそう、これはアップデートしないと」

rubysec/bundler-audit - GitHub


前編は以上です。

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

週刊Railsウォッチ: 端末文字幅とRubyのreline、SQLのプリペアドステートメント、Terraformほか(20220222後編)

今週の主なニュースソース

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

Rails公式ニュース

Ruby Weekly


CONTACT

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