Module: Flexselect

Defined in:
lib/flexselect.rb

Constant Summary collapse

DEFAULT =
{
  :block => lambda { |new| new },
  :if    => lambda { |new| !new.nil? },
  :on    => :before_validation
}

Instance Method Summary collapse

Instance Method Details

#attr_flex_selector(attr, options = {}, &block) ⇒ Object

Creates an virtual attribute to handle new values for an autocomplete select tag handled by flexquery and a callback to update the attribute using the virtual one.

The name of the virtual attribute and the callback is derived from the name of the attribute:

attr_flex_selector :thing

produces a virtual attribute named “flex_thing_input” and the private method “callback_for_flex_thing_input” for callback.

Options:

attr   :: The attribute to autocomple

:on    :: ActiveRecord callback to use for updating the attribute.
          Defaults to :before_validation_on_create

:if    :: A Proc that is called before updating the attribute.
          defaults to lambda { |virtual_attribute_value| virtual_attribute_value.present? }

&block :: If provided, is called to get the new value for the attribute.
          Defaults to lambda{ |virtual_attribute_value| virtual_attribute_value }

NOTE default values can be changed by tweaking the :block, :if and :on keys of the Flexselect::DEFAULT hash.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/flexselect.rb', line 36

def attr_flex_selector(attr, options = {}, &block)
  virtual_attribute = "flex_#{ attr }_input"
  callback_method   = "callback_for_#{ virtual_attribute }"

  attr_accessor virtual_attribute

  if_lambda     = options[:if] || DEFAULT[:if]
  action_lambda = block        || DEFAULT[:block]

  # A new Module allows to redefine method retaining the old one for "super" usage.
  mod = Module.new do
    define_method(callback_method) do
      value = send(virtual_attribute)

      if if_lambda.bind(self).call(value)
        send "#{attr}=", action_lambda.bind(self).call(value)
      end
    end
    private(callback_method)
  end

  include mod

  send(options[:on] || DEFAULT[:on], callback_method)
end