Class: Forms::Validations::Introspector
- Inherits:
-
Object
- Object
- Forms::Validations::Introspector
- Defined in:
- lib/forms/validations/introspector.rb
Overview
Introspects an ActiveModel class (or instance) and translates
each attribute's validators into a data: hash ready to merge
into a Phlex element. Phlex handles the data- prefixing and
underscore-to-hyphen conversion at render time.
Sticks to validators whose semantics are reproducible client
side. Skips anything with :if / :unless / :on because
those need server context the browser doesn't have. Server
validation remains authoritative — the client side just
shortens the loop for the common cases.
Defined Under Namespace
Classes: Null
Constant Summary collapse
- CONTROLLER_PREFIX =
"forms--validations"- SUPPORTED =
Validators we know how to mirror. Keys are the short class name (without namespace), values are the controller suffix appended to CONTROLLER_PREFIX. Matching on the short name picks up both
ActiveModel::Validations::*(form objects) andActiveRecord::Validations::*(AR models inherit a parallel set of subclasses for uniqueness/etc.) without listing both namespaces. { "PresenceValidator" => "presence", "LengthValidator" => "length", "FormatValidator" => "format", "NumericalityValidator" => "numericality", "InclusionValidator" => "inclusion", "ExclusionValidator" => "exclusion", "ConfirmationValidator" => "confirmation", "AcceptanceValidator" => "acceptance" }.freeze
- LENGTH_KEYS =
%i[maximum minimum is].freeze
- NUMERICALITY_KEYS =
%i[ greater_than greater_than_or_equal_to less_than less_than_or_equal_to equal_to other_than only_integer odd even ].freeze
Class Method Summary collapse
-
.for(model_or_class) ⇒ Object
Convenience: returns a null introspector for nil models so callers don't need to guard.
Instance Method Summary collapse
-
#data_attributes_for(attribute) ⇒ Object
Returns a hash of the shape: { controller: "forms--validations--presence forms--validations--length", forms__validations__presence_required_value: "true", forms__validations__length_maximum_value: "60", }.
-
#initialize(model_class) ⇒ Introspector
constructor
A new instance of Introspector.
Constructor Details
#initialize(model_class) ⇒ Introspector
Returns a new instance of Introspector.
56 57 58 |
# File 'lib/forms/validations/introspector.rb', line 56 def initialize(model_class) @model_class = model_class end |
Class Method Details
.for(model_or_class) ⇒ Object
Convenience: returns a null introspector for nil models so callers don't need to guard.
47 48 49 50 51 52 53 54 |
# File 'lib/forms/validations/introspector.rb', line 47 def self.for(model_or_class) return Null.new if model_or_class.nil? klass = model_or_class.is_a?(Class) ? model_or_class : model_or_class.class return Null.new unless klass.respond_to?(:validators_on) new(klass) end |
Instance Method Details
#data_attributes_for(attribute) ⇒ Object
Returns a hash of the shape:
{
controller: "forms--validations--presence forms--validations--length",
forms__validations__presence_required_value: "true",
forms__validations__length_maximum_value: "60",
}
Returns {} when no supported validators are present.
The double-underscore key encoding survives Phlex/Rails'
underscore-to-hyphen rewrite: __ → - (deliberate).
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/forms/validations/introspector.rb', line 70 def data_attributes_for(attribute) validators = applicable_validators(attribute) return {} if validators.empty? controllers = [] attrs = {} validators.each do |validator| suffix = SUPPORTED[validator.class.name.split("::").last] next unless suffix controllers << "#{CONTROLLER_PREFIX}--#{suffix}" value_attributes(suffix, validator, attribute).each do |key, value| attrs[data_key(suffix, key)] = value end end return {} if controllers.empty? { controller: controllers.uniq.join(" ") }.merge(attrs) end |