Class: PassthruValidator
- Inherits:
-
ActiveModel::EachValidator
- Object
- ActiveModel::EachValidator
- PassthruValidator
- Defined in:
- app/validators/passthru_validator.rb
Overview
This validator passes through the file upload validations on a record attribute to an associated record. Useful e.g. with the forms that are not aware of the actual record’s validators but they still need to apply the same validators as in the model they represent. Needs to be configured with the target class and optionally the target attribute where the validators are fetched from. By default the attribute name matches the attribute the validator is set for. Works only for each validators.
Example:
class ParticipantForm < Decidim::Form
# Passes both the validator class only
validates :avatar_image, passthru: { to: Person }
# Passes both the validator class and attribute
validates :image, passthru: { to: Person, attribute: :avatar_image }
end
Instance Method Summary collapse
- #target_attribute(default = nil) ⇒ Object
- #target_class ⇒ Object
- #target_instance(record) ⇒ Object
- #target_validators(attribute) ⇒ Object
- #validate_each(record, attribute, value) ⇒ Object
-
#validation_record(record) ⇒ Object
Creates a dummy validation record that passes the correct file upload validation context from the original record for the validators.
Instance Method Details
#target_attribute(default = nil) ⇒ Object
65 66 67 |
# File 'app/validators/passthru_validator.rb', line 65 def target_attribute(default = nil) [:attribute] || default end |
#target_class ⇒ Object
61 62 63 |
# File 'app/validators/passthru_validator.rb', line 61 def target_class [:to] end |
#target_instance(record) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'app/validators/passthru_validator.rb', line 69 def target_instance(record) instance_attributes = begin if [:with].respond_to?(:call) [:with].call(record) else [:with] || {} end end instance_attributes.each do |key, val| instance_attributes[key] = val.call(record) if val.respond_to?(:call) end target_class.new(instance_attributes) end |
#target_validators(attribute) ⇒ Object
57 58 59 |
# File 'app/validators/passthru_validator.rb', line 57 def target_validators(attribute) target_class.validators_on(target_attribute(attribute)) end |
#validate_each(record, attribute, value) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'app/validators/passthru_validator.rb', line 21 def validate_each(record, attribute, value) return unless target_class dummy_attr = target_attribute(attribute) # Create a dummy record for which the validations are actually run on dummy = validation_record(record) target_validators(attribute).each do |validator| next unless validator.is_a?(ActiveModel::EachValidator) next unless check_validator_conditions(dummy, validator) dummy.errors.clear validator.validate_each(dummy, dummy_attr, value) dummy.errors[dummy_attr].each do |err| record.errors.add(attribute, err) end end end |
#validation_record(record) ⇒ Object
Creates a dummy validation record that passes the correct file upload validation context from the original record for the validators.
43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'app/validators/passthru_validator.rb', line 43 def validation_record(record) dummy = target_instance(record) if dummy.is_a?(Decidim::Attachment) if record.respond_to?(:attached_to) dummy.attached_to = record.attached_to elsif record.respond_to?(:organization) dummy.attached_to = record.organization end elsif dummy.respond_to?(:organization=) && record.respond_to?(:organization) dummy.organization = record.organization end dummy end |