久しぶりにRailsのPRを眺める

初めに

久しぶりにRailsのPRを眺めてみることにした。すると一つ目についたものがあったので、備忘録の意味も込めて書くことにした

今回眺めたPR

今回見たのは、このPR。2022/12/28に見たときはまだDraftだった。今後これがどうなるか分からないが、このPRの中でActiveRecordwithメソッドという見慣れないものを使っていたので、これは何だろうかと少し調べてみた

withメソッドいつ実装された??

このPRで追加されたみたい。2022/12/28時点でmainブランチに取り込まれているのは確認した。

github.com

ただまだRailsの7.0.4には取り込まれていなかったので、mainブランチを使って検証してみました。

検証

やることは単純で例としてUserモデルを作ってみて、それに対しwithメソッドを使ってみる。どんなSQLが発行されるのか、見てみたいと思う。 下の例はnameとageというカラムを持つUserテーブルを作成し、それに対するmodelを作る。で、ageが10歳の人を抽出する処理をwithメソッドの中に書く。そしてto_sqlで発行されるSQLを確認。

3.1.1 :001 > User.with(ten_age_user: User.where('age = ?', 10))
  User Load (0.2ms)  WITH "ten_age_user" AS (SELECT "users".* FROM "users" WHERE (age = 10)) SELECT "users".* FROM "users" /* loading for pp */ LIMIT ?  [["LIMIT", 11]]
 => []
3.1.1 :002 > User.with(ten_age_user: User.where('age = ?', 10)).to_sql
 => "WITH \"ten_age_user\" AS (SELECT \"users\".* FROM \"users\" WHERE (age = 10)) SELECT \"users\".* FROM \"users\""

SQLのwith句が使えるようになるみたい。 試しにデータを追加して、このwithメソッドを使ってデータを抽出してみる。

3.1.1 :012 > ten_uesr = User.with(ten_age_user: User.where('age = ?', 10)).joins('join ten_age_user on ten_age_user.id = users.id')
  User Load (2.4ms)  WITH "ten_age_user" AS (SELECT "users".* FROM "users" WHERE (age = 10)) SELECT "users".* FROM "users" join ten_age_user on ten_age_user.id = users.id /* loading for pp */ LIMIT ?  [["LIMIT", 11]]
 => [#<User:0x0000000115266270 id: 3, name: "hoge3", age: 10, created_at: Wed, 28 Dec 2022 04:29:01.991160000 UTC +00:00, updated_at: Wed, 28 Dec 2022 04:29:01.991160000 UTC +00:00>]

これがあるとActiveRecordを使った抽出処理がSQLを書くイメージにより近づいたのかなと思う。 早くリリースされると良いなー。

最後に

久しぶりにrailsのPR見たけど、勉強になる。これは暫く続けるべきだと思った。