Module: Sequel::Plugins::FormeSet::InstanceMethods

Defined in:
lib/sequel/plugins/forme_set.rb

Instance Method Summary collapse

Instance Method Details

#forme_input(_form, field, _opts) ⇒ Object

Keep track of the inputs used.



32
33
34
# File 'lib/sequel/plugins/forme_set.rb', line 32

def forme_input(_form, field, _opts)
  forme_inputs[field] = super
end

#forme_inputsObject

Hash with column name symbol keys and Forme::SequelInput values



20
21
22
# File 'lib/sequel/plugins/forme_set.rb', line 20

def forme_inputs
  @forme_inputs ||= {}
end

#forme_parse(params) ⇒ Object

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.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/sequel/plugins/forme_set.rb', line 44

def forme_parse(params)
  hash = {}
  hash_values = hash[:values] = {}
  validations = hash[:validations] = {}

  forme_inputs.each do |field, input|
    opts = input.opts
    next if SKIP_FORMATTERS.include?(opts.fetch(:formatter){input.form.opts[:formatter]})

    if attr = opts[:attr]
      name = attr[:name] || attr['name']
    end
    name ||= opts[:name] || opts[:key] || next

    # Pull out last component of the name if there is one
    column = (name =~ /\[([^\[\]]+)\]\z/ ? $1 : name)
    column = column.to_s.sub(/\[\]\z/, '').to_sym

    hash_values[column] = params[column] || params[column.to_s]

    next unless ref = model.association_reflection(field)
    next unless options = opts[:options]

    values = if opts[:text_method]
      value_method = opts[:value_method] || opts[:text_method]
      options.map(&value_method)
    else
      options.map{|obj| obj.is_a?(Array) ? obj.last : obj}
    end

    if ref[:type] == :many_to_one && !opts[:required]
      values << nil
    end
    validations[column] = [ref[:type] != :many_to_one ? :subset : :include, values]
  end

  hash
end

#forme_set(params) ⇒ Object

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.



85
86
87
88
89
90
91
# File 'lib/sequel/plugins/forme_set.rb', line 85

def forme_set(params)
  hash = forme_parse(params)
  set(hash[:values])
  unless hash[:validations].empty?
    forme_validations.merge!(hash[:validations])
  end
end

#forme_validationsObject

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.



27
28
29
# File 'lib/sequel/plugins/forme_set.rb', line 27

def forme_validations
  @forme_validations ||= {}
end

#validateObject

Check associated values to ensure they match one of options in the form.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/sequel/plugins/forme_set.rb', line 94

def validate
  super

  if validations = @forme_validations
    validations.each do |column, (type, values)|
      value = send(column)

      valid = case type
      when :subset
        # Handle missing value the same as the empty array,
        # can happen with PostgreSQL array associations 
        !value || (value - values).empty?
      when :include
        values.include?(value)
      else
        raise Forme::Error, "invalid type used in forme_validations"
      end

      unless valid
        errors.add(column, 'invalid value submitted')
      end
    end
  end
end