class Reform::Form::Populator

Implements the :populator option.

populator: -> (fragment:, model:, :binding)
populator: -> (fragment:, collection:, index:, binding:)

For collections, the entire collection and the currently deserialised index is passed in.

Public Class Methods

new(user_proc) click to toggle source
# File lib/reform/form/populator.rb, line 8
def initialize(user_proc)
  @user_proc = user_proc # the actual `populator: ->{}` block from the user, via ::property.
  @value     = ::Representable::Option(user_proc) # we can now process Callable, procs, :symbol.
end

Public Instance Methods

call(input, options) click to toggle source
# File lib/reform/form/populator.rb, line 13
def call(input, options)
  model = get(options)
  twin  = call!(options.merge(model: model, collection: model))

  return twin if twin == Representable::Pipeline::Stop

  # this kinda sucks. the proc may call self.composer = Artist.new, but there's no way we can
  # return the twin instead of the model from the #composer= setter.
  twin = get(options) unless options[:binding].array?

  # we always need to return a twin/form here so we can call nested.deserialize().
  handle_fail(twin, options)

  twin
end

Private Instance Methods

call!(options) click to toggle source
# File lib/reform/form/populator.rb, line 31
def call!(options)
  form = options[:represented]
  evaluate_option(form, options)
end
evaluate_option(form, options) click to toggle source
# File lib/reform/form/populator.rb, line 36
def evaluate_option(form, options)
  if @user_proc.is_a?(Uber::Callable) && @user_proc.method(:call).arity == 2 # def call(form, options)
    warn %{[Reform] Accepting `form` as a positional argument in `:populator` will be deprecated. Please use `def call(form:, **options)` signature instead.}

    return @value.(form, exec_context: form, keyword_arguments: options)
  end

  @value.(exec_context: form, keyword_arguments: options.merge(form: form)) # Representable::Option call
end
get(options) click to toggle source
# File lib/reform/form/populator.rb, line 50
def get(options)
  Representable::GetValue.(nil, options)
end
handle_fail(twin, options) click to toggle source
# File lib/reform/form/populator.rb, line 46
def handle_fail(twin, options)
  raise "[Reform] Your :populator did not return a Reform::Form instance for `#{options[:binding].name}`." if options[:binding][:nested] && !twin.is_a?(Reform::Form)
end