- Ruby / Rails関連
週刊Railsウォッチ: dartsass-railsがリリース、webpack-mergeツール、Rubyが29歳にほか(20220228前編)
こんにちは、hachi8833です。つっつきの日がお誕生日でした🎉
今日はRubyの29歳の誕生日では。おめでとう!いつもありがとう!
— igaiga (@igaiga555) February 23, 2022
Happy Birthday, Ruby! 🌸
Ruby language was born (well, actually named) on February 24th, 1993 🙌
Choosing to work with Ruby at the beginning of my career is still the best decision I ever made.
Thanks, @yukihiro_matz 🙌 Lucky to meet you at Ruby conf 😊#Ruby #RubyOnRails pic.twitter.com/nkHziCaH6b
— Rishi Pithadiya (@rishipi) February 23, 2022
🔗Rails: 先週の改修(Rails公式ニュースより)
公式更新情報で1件見逃していたものがあったので、そこから見繕いました。
🔗 Object
のinstance_values
を最適化
#44257のフォローアップ。
#44213のレビューでas_json
のパフォーマンスを調べてみた。Object#instance_variable_names
ではシンプルな最適化がいくつか行えた。
Array#to_h
は本質的にHash::[]
よりかなり高速(インターフェイスが厳密で正しいサイズのハッシュを事前にアロケーションできる)。
また、Hash#[]
で文字列が重複しないよう早い段階でfreeze
させる。
#44258より
つっつきボイス:「instance_variable_names
の方は少し前にも見た覚えがありますね(ウォッチ20220131)」
- Rails API:
Object#instance_values
# 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#human
とhuman_attribute_name
を最適化
- PR: Improve
ActiveModel::Name#human
performance by jonathanhefner · Pull Request #44299 · rails/rails - PR: Improve
human_attribute_name
performance by jonathanhefner · Pull Request #44300 · rails/rails
ActiveModel::Name#human
のアロケーションを削減して、訳文が定義されていない場合のパフォーマンスを2倍程度改善するリファクタリング。
#44299より
つっつきボイス:「human
やhuman_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ぐらいしか思いつかない」
🔗 ガイド改修
逆関連付けが具体的に何をするのか戸惑ったことを思い出す。このガイドは役に立ったが、いくつかのユースケースが抜けている。それらをまとめてコード例とともにドキュメント化することで、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公式更新情報のエントリをここに置きました」「Dart Sass↓のバイナリ版がdartsass-railsに入ったので、DartをインストールしなくてもSassが使えるようになったんですね」
「そういえばこの間記事にしたtailwindcss-railsもバイナリ版のツールを使うところがちょっと似ていますね↓」
「見たところ他のプラットフォームでは普通にバイナリを使うけど、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のコンフィグをマージするツール
つっつきボイス:「お〜、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
- 元記事: Introducing Propshaft(Ruby Weeklyより)
- リリース: Release 1.13.2 / 2022-02-21 · sparklemotion/nokogiri(セキュリティ修正) -- 現在は1.13.3です
つっつきボイス:「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くんが知らせてくれました↓」「そうそう、これはアップデートしないと」
前編は以上です。
バックナンバー(2022年度第1四半期)
週刊Railsウォッチ: 端末文字幅とRubyのreline、SQLのプリペアドステートメント、Terraformほか(20220222後編)
- 20220221前編 orderでコレーション指定をサポート、awesome_nested_set、GitHub Copilotほか
- 20220216後編 Bundler自身のバージョンロック機能、gem署名メカニズムの提案ほか
- 20220214前編 Rails 7.0.2の改修内容、receipts gemでレシートを作成ほか
- 20220209後編 Rubygems.orgのAPIキーに権限スコープが追加、RailsのDBパフォーマンス改善ほか
- 20220208前編 Rails 6.1を7.0にアップグレードしてみた、PostgreSQLでジョブキューほか
- 20220201後編 Rubygems Adoptionフォームが開設、JetBrains Gateway、NGINX Unitほか
- 20220131前編 Sidekiqが10歳に、BuildKiteのテストを高速化、フィーチャーフラグほか
- 20220126後編 Rubyコンパイラの歴史動画、RubyのWebAssembly対応進む、ぼっち演算子の注意点ほか
- 20220124前編 Webpackerが公式に引退宣言、『Everyday Rails』日本語版がRails 7に対応ほか
- 20220118後編 Ruby 2.5〜3.1ベンチマーク、Opal 1.4、JRubyが20歳に、2022年のCSSほか
- 20220117前編 rails-ujs->Turboアップグレードガイド、RubyとWeb Componentsほか
- 20220112 Rails 7をRuby 3.1で動かす、クックパッドのRuby 3.1解説記事、Rails 6->7更新ほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。
週刊Railsウォッチについて
TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)