module ActiveModel::Attributes::Normalization

def normalize_attribute(name)

User.normalize_value_for(:phone, "+1 (555) 867-5309") # => "5558675309"

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

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

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
To prevent confusion, normalization will not be applied

==== Behavior with Active Record

legacy_user.email # => "cruise-control@example.com"
legacy_user.normalize_attribute(:email)
legacy_user.email # => " CRUISE-CONTROL@EXAMPLE.COM\n"
legacy_user = User.load_from_legacy_data(...)

end
normalizes :email, with: -> email { email.strip.downcase }

attribute :email, :string

include ActiveModel::Attributes::Normalization
include ActiveModel::Attributes
class User

==== Examples

Normalizes a specified attribute using its declared normalizations.
def normalize_attribute(name)
  # Treat the value as a new, unnormalized value.
  send(:"#{name}=", send(name))
end

def normalize_changed_in_place_attributes

def normalize_changed_in_place_attributes
  self.class.normalized_attributes.each do |name|
    normalize_attribute(name) if attribute_changed_in_place?(name)
  end
end