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
record - Form object (e.g. Decidim::UploadValidationForm) attribute - The attribute to validate (e.g. :avatar) value - Blob’s signed id (e.g. “eyJfcmFpbHMi…”).
-
#validation_record(record) ⇒ Object
Creates a dummy validation record that passes the correct file upload validation context from the original record for the validators.
- #validation_record_context(dummy, record) ⇒ Object
Instance Method Details
permalink #target_attribute(default = nil) ⇒ Object
[View source]
87 88 89 |
# File 'app/validators/passthru_validator.rb', line 87 def target_attribute(default = nil) [:attribute] || default end |
permalink #target_class ⇒ Object
[View source]
83 84 85 |
# File 'app/validators/passthru_validator.rb', line 83 def target_class [:to] end |
permalink #target_instance(record) ⇒ Object
[View source]
91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'app/validators/passthru_validator.rb', line 91 def target_instance(record) instance_attributes = if [:with].respond_to?(:call) [:with].call(record) else [:with] || {} 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 |
permalink #target_validators(attribute) ⇒ Object
[View source]
79 80 81 |
# File 'app/validators/passthru_validator.rb', line 79 def target_validators(attribute) target_class.validators_on(target_attribute(attribute)) end |
permalink #validate_each(record, attribute, value) ⇒ Object
record - Form object (e.g. Decidim::UploadValidationForm) attribute - The attribute to validate (e.g. :avatar) value - Blob’s signed id (e.g. “eyJfcmFpbHMi…”)
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'app/validators/passthru_validator.rb', line 24 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) if dummy.respond_to?(dummy_attr) && !(value.class <= ActiveStorage::Attached) dummy.public_send("#{dummy_attr}=", value) value = dummy.public_send(dummy_attr) elsif dummy.respond_to? :file dummy.public_send("file=", value) value = dummy.public_send(:file) end 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 |
permalink #validation_record(record) ⇒ Object
Creates a dummy validation record that passes the correct file upload validation context from the original record for the validators.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'app/validators/passthru_validator.rb', line 54 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 validation_record_context(dummy, record) dummy end |
permalink #validation_record_context(dummy, record) ⇒ Object
[View source]
69 70 71 72 73 74 75 76 77 |
# File 'app/validators/passthru_validator.rb', line 69 def validation_record_context(dummy, record) if dummy.is_a?(Decidim::Form) dummy.with_context( current_organization: record.try(:current_organization) || record.try(:ganization), current_participatory_space: record.try(:current_participatory_space) || record.try(:participatory_space), current_component: record.try(:current_component) || record.try(:component) ) end end |