Class: Snails::Form
- Defined in:
- runtime/snails/form.rbs,
runtime/snails/form/errors.rbs,
runtime/snails/form/rule_engine.rbs,
runtime/snails/form/rule_options.rbs,
runtime/snails/form.rb,
runtime/snails/form/errors.rb,
runtime/snails/form/rule_engine.rb,
runtime/snails/form/rule_options.rb
Defined Under Namespace
Classes: Errors
Constant Summary collapse
- VALIDATIONS =
---- declaration registries (module-level, owner-partitioned) ----- Array constants, not class ivars: spinel does not carry a class ivar into a subclass, and a class-body registration lands here with the owner's class name.
[]
- MESSAGE_SCOPES =
[]
- DEFAULT_RULE_OPTIONS =
Options that may sit at the
validatescall level and apply to every rule in that call —validates :email, presence: true, if: :ready?. A rule-level option of the same name wins. [ :if, :unless, :allow_nil, :allow_blank ]
- COMMON_RULE_OPTIONS =
The options every rule accepts, and the options each rule brings on top. The rule-name allowlist is the hash's keys: an unknown rule or option key in
validatesis rejected at declaration time, never ignored at validation time. [ :message, :allow_nil, :allow_blank, :if, :unless ]
- RULE_DECLARATION_OPTIONS =
{ presence: [], length: [ :minimum, :maximum, :is, :within, :in ], format: [ :with, :without ], inclusion: [ :in ], exclusion: [ :in ], uniqueness: [ :model, :column, :scope ], confirmation: [], }
Class Method Summary collapse
-
.field_names ⇒ Array[String]
the field names this form declares, as written in its
FIELDSaccessor loop (the projection filter and thevalidates/errors.adddeclaration check's registry). -
.message_scope(scope) ⇒ void
point this form's error keys at a locale subtree.
-
.validate(*method_names, **options) ⇒ void
register an instance method as a custom validation.
-
.validates(*attributes, **rules) ⇒ void
register rules for declared fields.
Instance Method Summary collapse
-
#errors ⇒ Errors
the current error list: empty until a rule or custom method fails, replaced by every
valid?call. -
#human_attribute_name(attribute) ⇒ String
the display name a full message prefixes (
email->Email,password_confirmation->Password confirmation). -
#initialize(values = {}) ⇒ Form
constructor
project the input hash onto the declared fields through the write seam, then run the
normalizehook. -
#normalize ⇒ void
the input-normalization hook, called once from
newbefore validation reads any value. -
#read_attribute(name) ⇒ untyped
the read seam of the field-storage path: every generated reader and the rule engine route through this one method, so the value path holds no dynamic dispatch.
-
#valid? ⇒ bool
reset the error list, run this class's registered validations in registration order, and answer whether the input is clean.
-
#write_attribute(name, value) ⇒ untyped
the write seam (there are no generated setters: spinel refuses an interpolated
define_methodname, so writes stay a plain call).
Constructor Details
#initialize(values = {}) ⇒ Form
project the input hash onto the declared fields through the write seam,
then run the normalize hook. Keys are matched against FIELDS (String
and Symbol input keys both — HTTP params carry Strings; a later key wins
when both spellings are present, following hash order), so keys outside
the declaration are ignored: HTTP input is a superset by nature, and an
input key can never reach framework state (errors) because it is not a
field. A field the input never carried reads nil.
191 |
# File 'runtime/snails/form.rb', line 191
def initialize: (?Hash[untyped, untyped] values) -> void
|
Class Method Details
.field_names ⇒ Array[String]
the field names this form declares, as written in its FIELDS accessor
loop (the projection filter and the validates/errors.add declaration
check's registry).
51 |
# File 'runtime/snails/form.rb', line 51
def self.field_names: () -> Array[String]
|
.message_scope(scope) ⇒ void
point this form's error keys at a locale subtree. Without it, keys resolve
under activemodel.errors.models.<form_name>.attributes.
171 |
# File 'runtime/snails/form.rb', line 171
def self.message_scope: (untyped scope) -> void
|
.validate(*method_names, **options) ⇒ void
register an instance method as a custom validation. It runs in
registration order like a rule and reports through errors.add, for
conditions the declarative rules do not express (short-circuits,
cross-field rules). if:/ unless: guard the call with a Symbol method
name, as on a rule. The method is dispatched with send, so a typo'd name
raises NoMethodError at the first valid? instead of skipping silently.
146 |
# File 'runtime/snails/form.rb', line 146
def self.validate: (*Symbol method_names, **untyped options) -> void
|
.validates(*attributes, **rules) ⇒ void
register rules for declared fields. Rules run in registration order during
valid?, and the errors keep that order — an HTTP 422 body is an ordered
message list, so declaration order is the contract. One call may name
several fields; each rule's attributes are registered together, before the
next rule's (rule-major).
Common options may sit at the call level and apply to every rule
in the call — validates :email, presence: true, if: :ready? —
or inside one rule's hash; a rule-level option wins.
88 |
# File 'runtime/snails/form.rb', line 88
def self.validates: (*Symbol attributes, **untyped rules) -> void
|
Instance Method Details
#errors ⇒ Errors
the current error list: empty until a rule or custom method fails,
replaced by every valid? call.
262 |
# File 'runtime/snails/form.rb', line 262
def errors: () -> Errors
|
#human_attribute_name(attribute) ⇒ String
the display name a full message prefixes (email -> Email,
password_confirmation -> Password confirmation). Override to carry
locale names.
272 |
# File 'runtime/snails/form.rb', line 272
def human_attribute_name: (Symbol attribute) -> String
|
#normalize ⇒ void
the input-normalization hook, called once from new before validation
reads any value. Override it for strips, downcasing, defaults — write
through write_attribute (there are no generated setters); input shaping
only, never persistence.
282 |
# File 'runtime/snails/form.rb', line 282
def normalize: () -> void
|
#read_attribute(name) ⇒ untyped
the read seam of the field-storage path: every generated reader and the rule engine route through this one method, so the value path holds no dynamic dispatch. A missing field answers nil.
211 |
# File 'runtime/snails/form.rb', line 211
def read_attribute: (untyped name) -> untyped
|
#valid? ⇒ bool
reset the error list, run this class's registered validations in
registration order, and answer whether the input is clean. Rule guards
(if/unless/allow_nil/allow_blank) decide what each rule may
report, and custom validate methods run in the same order — so
errors.full_messages reflects declaration order, the ordered-list
contract a 422 body depends on. Calling it again starts from an empty
list.
240 |
# File 'runtime/snails/form.rb', line 240
def valid?: () -> bool
|
#write_attribute(name, value) ⇒ untyped
the write seam (there are no generated setters: spinel refuses an
interpolated define_method name, so writes stay a plain call). The
projection and the normalize hook write here. Input only — no dirty
tracking; a name outside FIELDS is a caller bug and fails loud instead
of storing a value no reader will see.
224 |
# File 'runtime/snails/form.rb', line 224
def write_attribute: (untyped name, untyped value) -> untyped
|