4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rails6.1でRubyを3.2にしたらスコープでキーワード引数が使えなくなった

Posted at

背景

ruby on railsで開発しているのですが、rubyのバージョンを上げようと思ったら躓いてしまいました。日本語だとあまり情報がなかったので記事にしてみました。

railsとrubyのバージョンは下記の通り。
rails: 6.1.7.7
ruby: 3.0.6 -> 3.2.3

そもそもスコープってなに?というかたは、こちらのリンクとかが参考になるかもしれません。
私が開発しているアプリでは、モデルの中でよく使う条件式をわかりやすい名前のスコープとして定義したりしてます。

何が起きたのか?

例えば下記のようなスコープがあったとします。
(実際はキーワード引数を使う必要はないと思いますが、あくまで例なので悪しからず)

User < ApplicationRecord
    scope :younger_than,
          lambda { |age:|
            where(age: ...age)
          }
end

使うときは、こんな感じでクラスメソッドのように使えます。

User.younger_than(age: 10)
> SELECT `users`.* FROM `users` WHERE `users`.`age` < 10 # こんなSQLが発行される
> [#<User id: 1, age: 5, ...>,
>  #<User id: 3, age: 9, ...>] # ageが10未満のレコードを含むActiveRecord::Relationが返ってくる

railsのスコープは上記のようにキーワード引数が使えるのですが、rubyのバージョンを3.2にあげたところ下記のようなエラーが出るようになりました。

User.younger_than(age: 10)
> wrong number of arguments (given 1, expected 0; required keywords:age) (ArgumentError)

どうやらキーワード引数ではなく、ハッシュが位置引数として渡ってしまっているようです。

原因と対策

色々調べていると、railsのgithubで同様の問題をissueであげている人がいました。
issueの中を読んでみると、ruby 3.2からキーワード引数と扱い方が変わったらしく、それが影響してスコープでキーワード引数が使えなくなるとのこと。

しかも、残念ながらrails 6.1はセキュリティ対応のみ更新していく状態なので、今回のようなバグ対応はしないと、メンテナーから回答されていました。
一応対応したrails:6-1-stableというブランチがあり、railsがリリースされるたびにこちらのブランチも更新されているようですが、リリースされているわけではないです。

というわけで対策は下記のどれかとなります。

  1. スコープのキーワード引数を位置引数の変える
  2. スコープをクラスメソッドにする
  3. ruby 3.1のままにする
  4. rails7にあげる

rails7に早くあげたいところではありますが、大仕事なのは目に見えているので、一旦スコープのキーワード引数を位置引数に変えて、計画的にrails7へあげていくことにしました。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?