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

Rails 7.1: Active Modelバリデーションのin・withinオプションでbeginless/endless rangeをサポート(翻訳)

概要

元サイトの許諾を得て翻訳・公開いたします。

日本語タイトルは内容に即したものにしました。

参考: 週刊Railsウォッチ20220531: バリデーションのinwithinでbeginless/endless rangeをサポート

参考: Edge API ActiveModel::Validations::Length -- private
参考: Edge API ActiveModel::Validations::Clusivity -- private
参考: Clusivity - Wikipedia

Rails 7.1: Active Modelバリデーションの:in:withinオプションでbeginless/endless rangeをサポート(翻訳)

Rails 7.1で、Active Modelバリデーションで:inオプションや:withinオプションを使う場合に、いわゆるbeginless/endlessのrangeをサポートするようになりました。

既に、以下のようにbeginlessやendlessのrangeを使うクエリは(Rails 7.0の)Active Recordで利用可能です。

Book.where(purchases: 20..)
# `purchases`が20件以上あるレコードのコレクションを返す
Book.where(purchases: ..20)
# `purchase`が20件以下のレコードのコレクションを返す

しかしActive Modelのバリデーションで同様のbeginless/endlessのrangeを使おうとすると、利用範囲が限られていました。
Rails 7.1では、Active Modelバリデーションでbeginless/endlessのrangeをサポートする形で利用範囲を拡張しています。たとえば、あるUserfirst_nameの長さを上限指定なしでバリデーションする場合は、以下のようにin: 20..でシンプルに書けます。

class User
    # ...
    validates_length_of :first_name, in: 20..
end

上の:first_nameの長さ指定には上限がないので、長さが20以上である限り有効です。

:withinオプションでも上の例と同じことができます。

class User
    # ...
    validates_length_of :first_name, within: 20..
end

同様に、Active Recordバリデーションで:inclusionオプションを併用した場合を見てみましょう。

class User
    # ...
    validates :age, inclusion: { in: proc { (25..) } }
end

この例では、レコードが有効であるためには:ageフィールドの値が25以上である必要があります。

詳しくは以下のプルリクをご覧ください。

  1. Support infinite ranges for LengthValidators :in/:within options by fatkodima · Pull Request #45138 · rails/rails
  2. Add beginless range support to clusivity by bjeanes · Pull Request #45123 · rails/rails

関連記事

Rails 7.1: config.active_storage.serviceが未設定の場合にRuntimeErrorで通知(翻訳)

Rails 7.1: Action Cableコマンドにコネクションレベルのコールバックが追加(翻訳)


CONTACT

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