module ActiveRecord::Normalization::ClassMethods
def normalizes(*names, with:, apply_to_nil: false)
User.exists?(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]) # => false
User.exists?(email: "\tCRUISE-CONTROL@EXAMPLE.COM ") # => true
User.where(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]).count # => 0
User.where(email: "\tCRUISE-CONTROL@EXAMPLE.COM ").count # => 1
user.email_before_type_cast # => "cruise-control@example.com"
user.email # => "cruise-control@example.com"
user = User.find_by(email: "\tCRUISE-CONTROL@EXAMPLE.COM ")
user.email # => "cruise-control@example.com"
user = User.create(email: " CRUISE-CONTROL@EXAMPLE.COM\n")
end
normalizes :phone, with: -> phone { phone.delete("^0-9").delete_prefix("1") }
normalizes :email, with: -> email { email.strip.downcase }
class User < ActiveRecord::Base
==== Examples
Defaults to +false+.
* +:apply_to_nil+ - Whether to apply the normalization to +nil+ values.
its sole argument, and returns it normalized.
* +:with+ - Any callable object that accepts the attribute's value as
==== Options
and raise +TypeError+.
Otherwise, +Marshal+ may attempt to serialize the normalization +Proc+
config.active_record.marshalling_format_version = 7.1.
higher via either config.load_defaults 7.1 or
then you should set ActiveRecord.marshalling_format_version to +7.1+ or
marshals instances of the targeted model (for example, when caching),
Be aware that if your app was created before Rails 7.1, and your app
behavior can be changed with the +:apply_to_nil+ option.
By default, the normalization will not be applied to +nil+ values. This
should have the same result as applying it only once.
_idempotent_. In other words, applying the normalization more than once
Because the normalization may be applied multiple times, it should be
value, or it is explicitly migrated via Normalization#normalize_attribute.
attribute will not be normalized until either it is assigned a new
record was persisted before the normalization was declared, the record's
when the attribute is fetched from the database. This means that if a
However, to prevent confusion, the normalization will not be applied
values.
allows a record to be created and later queried using unnormalized
applied to the corresponding keyword argument of query methods. This
value will be persisted to the database. The normalization is also
is applied when the attribute is assigned or updated, and the normalized
Declares a normalization for one or more attributes. The normalization
def normalizes(*names, with:, apply_to_nil: false) names.each do |name| attribute(name) do |cast_type| NormalizedValueType.new(cast_type: cast_type, normalizer: with, normalize_nil: apply_to_nil) end end self.normalized_attributes += names.map(&:to_sym) end