module Sequel::Plugins::FormeSet::InstanceMethods
Public Instance Methods
Keep track of the inputs used.
# File lib/sequel/plugins/forme_set.rb 51 def forme_input(_form, field, _opts) 52 frozen? ? super : (forme_inputs[field] = super) 53 end
Hash with column name symbol keys and Forme::SequelInput
values
# File lib/sequel/plugins/forme_set.rb 22 def forme_inputs 23 return (@forme_inputs || {}) if frozen? 24 @forme_inputs ||= {} 25 end
Given the hash of submitted parameters, return a hash containing information on how to set values in the model based on the inputs used on the related form. Currently, the hash contains the following information:
- :values
-
A hash of values that can be used to update the model, suitable for passing to Sequel::Model#set.
- :validations
-
A hash of values suitable for merging into forme_validations. Used to check that the submitted values for associated objects match one of the options for the input in the form.
# File lib/sequel/plugins/forme_set.rb 63 def forme_parse(params) 64 hash = {} 65 hash_values = hash[:values] = {} 66 validations = hash[:validations] = {} 67 68 forme_inputs.each do |field, input| 69 next unless column = forme_column_for_input(input) 70 hash_values[column] = params[column] || params[column.to_s] 71 72 next unless validation = forme_validation_for_input(field, input) 73 validations[column] = validation 74 end 75 76 hash 77 end
Set the values in the object based on the parameters parsed from the form, and add validations based on the form to ensure that associated objects match form values.
# File lib/sequel/plugins/forme_set.rb 81 def forme_set(params) 82 hash = forme_parse(params) 83 set(hash[:values]) 84 unless hash[:validations].empty? 85 forme_validations.merge!(hash[:validations]) 86 end 87 nil 88 end
Hash with column name symbol keys and [subset, allowed_values]
values. subset
is a boolean flag, if true, the uploaded values should be a subset of the allowed values, otherwise, there should be a single uploaded value that is a member of the allowed values.
# File lib/sequel/plugins/forme_set.rb 45 def forme_validations 46 return (@forme_validations || {}) if frozen? 47 @forme_validations ||= {} 48 end
Temporarily reset forme_inputs
to the empty hash before yielding to the block.
Used by the Roda
forme_set
plugin to make sure each form only includes metadata for inputs in that form, and not metadata for inputs for earlier forms on the same page.
# File lib/sequel/plugins/forme_set.rb 30 def isolate_forme_inputs 31 return yield if frozen? 32 33 forme_inputs = self.forme_inputs 34 begin 35 @forme_inputs = {} 36 yield 37 ensure 38 @forme_inputs = forme_inputs.merge(@forme_inputs) 39 end 40 end
Check associated values to ensure they match one of options in the form.
# File lib/sequel/plugins/forme_set.rb 91 def validate 92 super 93 94 if validations = @forme_validations 95 validations.each do |column, (type, values)| 96 value = send(column) 97 98 valid = case type 99 when :subset 100 # Handle missing value the same as the empty array, 101 # can happen with PostgreSQL array associations 102 !value || (value - values).empty? 103 when :include 104 values.include?(value) 105 when :valid 106 values 107 else 108 raise Forme::Error, "invalid type used in forme_validations" 109 end 110 111 unless valid 112 errors.add(column, 'invalid value submitted') 113 end 114 end 115 end 116 end
Private Instance Methods
Return the model column name to use for the given form input.
# File lib/sequel/plugins/forme_set.rb 121 def forme_column_for_input(input) 122 opts = input.opts 123 return if SKIP_FORMATTERS.include?(opts.fetch(:formatter){input.form_opts[:formatter]}) 124 125 attr = opts[:attr] || {} 126 return unless name ||= attr[:name] || attr['name'] || opts[:name] || opts[:key] 127 128 # Pull out last component of the name if there is one 129 column = name.to_s.chomp('[]') 130 if column =~ /\[([^\[\]]+)\]\z/ 131 $1 132 else 133 column 134 end.to_sym 135 end
Return the validation metadata to use for the given field name and form input.
# File lib/sequel/plugins/forme_set.rb 138 def forme_validation_for_input(field, input) 139 return unless ref = model.association_reflection(field) 140 opts = input.opts 141 return unless options = opts[:options] 142 143 values = if opts[:text_method] 144 value_method = opts[:value_method] || opts[:text_method] 145 options.map(&value_method) 146 else 147 options.map{|obj| obj.is_a?(Array) ? obj.last : obj} 148 end 149 150 if ref[:type] == :many_to_one && !opts[:required] 151 values << nil 152 end 153 [ref[:type] != :many_to_one ? :subset : :include, values] 154 end