Module: ActiveModel::Attributes::Normalization
| Relationships & Source Files | |
| Namespace Children | |
|
Modules:
| |
|
Classes:
| |
| Extension / Inclusion / Inheritance Descendants | |
|
Included In:
| |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
::ActiveSupport::Concern
|
|
| Defined in: | activemodel/lib/active_model/attributes/normalization.rb |
Class Method Summary
::ActiveSupport::Concern - Extended
| class_methods | Define class methods from given block. |
| included | Evaluate given block in context of base class, so that you can write class macros here. |
| prepended | Evaluate given block in context of base class, so that you can write class macros here. |
| append_features, prepend_features | |
Instance Method Summary
-
#normalize_attribute(name)
Normalizes a specified attribute using its declared normalizations.
- #normalize_changed_in_place_attributes private
- #normalized_attribute_changed_in_place?(attribute) ⇒ Boolean private
DSL Calls
included
[ GitHub ]9 10 11 12 13 14 15 16
# File 'activemodel/lib/active_model/attributes/normalization.rb', line 9
included do include ActiveModel::Dirty include ActiveModel::Validations::Callbacks class_attribute :normalized_attributes, default: Set.new.freeze before_validation :normalize_changed_in_place_attributes end
Instance Method Details
#normalize_attribute(name)
Normalizes a specified attribute using its declared normalizations.
Examples
class User
include ActiveModel::Attributes
include ActiveModel::Attributes::Normalization
attribute :email, :string
normalizes :email, with: -> email { email.strip.downcase }
end
legacy_user = {User.load_from_legacy_data}(...)
legacy_user.email # => " CRUISE-CONTROL@EXAMPLE.COM\n"
legacy_user.normalize_attribute(:email)
legacy_user.email # => "cruise-control@example.com"
Behavior with Active Record
To prevent confusion, normalization will not be applied
when the attribute is fetched from the database. This means that if a
record was persisted before the normalization was declared, the record's
attribute will not be normalized until either it is assigned a new
value, or it is explicitly migrated via #normalize_attribute.
Be aware that if your app was created before Rails 7.1, and your app
marshals instances of the targeted model (for example, when caching),
then you should set ActiveRecord.marshalling_format_version to 7.1 or
higher via either config.load_defaults 7.1 or
config.active_record.marshalling_format_version = 7.1.
Otherwise, Marshal may attempt to serialize the normalization Proc
and raise TypeError.
class User < {ActiveRecord::Base}
normalizes :email, with: -> email { email.strip.downcase }
normalizes :phone, with: -> phone { phone.delete("^0-9").delete_prefix("1") }
end
user = {User.create}(email: " CRUISE-CONTROL@EXAMPLE.COM\n")
user.email # => "cruise-control@example.com"
user = {User.find_by}(email: "\tCRUISE-CONTROL@EXAMPLE.COM ")
user.email # => "cruise-control@example.com"
user.email_before_type_cast # => "cruise-control@example.com"
{User.where}(email: "\tCRUISE-CONTROL@EXAMPLE.COM ").count # => 1
{User.where}(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]).count # => 0
{User.exists?}(email: "\tCRUISE-CONTROL@EXAMPLE.COM ") # => true
{User.exists?}(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]) # => false
{User.normalize_value_for}(:phone, "+1 (555) 867-5309") # => "5558675309"
# File 'activemodel/lib/active_model/attributes/normalization.rb', line 75
def normalize_attribute(name) # Treat the value as a new, unnormalized value. send(:"#{name}=", send(name)) end
#normalize_changed_in_place_attributes (private)
[ GitHub ]# File 'activemodel/lib/active_model/attributes/normalization.rb', line 149
def normalize_changed_in_place_attributes self.class.normalized_attributes.each do |name| attribute = @attributes[name.to_s] normalize_attribute(name) if normalized_attribute_changed_in_place?(attribute) end end