Module: Formtastic::Inputs::Base::Collections

Included in:
CheckBoxesInput, RadioInput, SelectInput
Defined in:
lib/formtastic/inputs/base/collections.rb

Instance Method Summary collapse

Instance Method Details

#collectionObject



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/formtastic/inputs/base/collections.rb', line 37

def collection
  # Return if we have a plain string
  return raw_collection if raw_collection.instance_of?(String) || raw_collection.instance_of?(ActiveSupport::SafeBuffer)

  # Return if we have an Array of strings, fixnums or arrays
  return raw_collection if (raw_collection.instance_of?(Array) || raw_collection.instance_of?(Range)) &&
                       [Array, Fixnum, String, Symbol].include?(raw_collection.first.class) &&
                       !(options.include?(:member_label) || options.include?(:member_value))

  raw_collection.map { |o| [send_or_call(label_method, o), send_or_call(value_method, o)] }
end

#collection_for_booleanObject



73
74
75
76
77
78
79
80
# File 'lib/formtastic/inputs/base/collections.rb', line 73

def collection_for_boolean
  true_text = options[:true] || Formtastic::I18n.t(:yes)
  false_text = options[:false] || Formtastic::I18n.t(:no)

  # TODO options[:value_as_class] = true unless options.key?(:value_as_class)

  [ [true_text, true], [false_text, false] ]
end

#collection_from_associationObject



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/formtastic/inputs/base/collections.rb', line 55

def collection_from_association
  if reflection
    raise PolymorphicInputWithoutCollectionError.new("A collection must be supplied for #{method} input. Collections cannot be guessed for polymorphic associations.") if reflection.options && reflection.options[:polymorphic] == true

    find_options_from_options = options[:find_options] || {}
    conditions_from_options = find_options_from_options[:conditions] || {}
    conditions_from_reflection = reflection.options && reflection.options[:conditions] || {}
    conditions_from_reflection = conditions_from_reflection.call if conditions_from_reflection.is_a?(Proc)

    if conditions_from_options.any?
      reflection.klass.scoped(:conditions => conditions_from_reflection).where(conditions_from_options)
    else
      find_options_from_options.merge!(:include => group_by) if self.respond_to?(:group_by) && group_by
      reflection.klass.scoped(:conditions => conditions_from_reflection).where(find_options_from_options)
    end
  end
end

#collection_from_optionsObject



49
50
51
52
53
# File 'lib/formtastic/inputs/base/collections.rb', line 49

def collection_from_options
  items = options[:collection]
  items = items.to_a if items.is_a?(Hash)
  items
end

#label_and_value_method(_collection, grouped = false) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/formtastic/inputs/base/collections.rb', line 14

def label_and_value_method(_collection, grouped=false)
  sample = _collection.first || _collection.last

  case sample
  when Array
    label, value = :first, :last
  when Integer
    label, value = :to_s, :to_i
  when String, NilClass
    label, value = :to_s, :to_s
  end

  # Order of preference: user supplied method, class defaults, auto-detect
  label = (grouped ? options[:grouped_label_method] : options[:member_label]) || label || builder.collection_label_methods.find { |m| sample.respond_to?(m) }
  value = (grouped ? options[:grouped_value_method] : options[:member_value]) || value || builder.collection_value_methods.find { |m| sample.respond_to?(m) }

  [label, value]
end

#label_methodObject



6
7
8
# File 'lib/formtastic/inputs/base/collections.rb', line 6

def label_method
  label_and_value_method(raw_collection).first
end

#raw_collectionObject



33
34
35
# File 'lib/formtastic/inputs/base/collections.rb', line 33

def raw_collection
  @raw_collection ||= (collection_from_options || collection_from_association || collection_for_boolean)
end

#send_or_call(duck, object) ⇒ Object



82
83
84
85
86
87
88
# File 'lib/formtastic/inputs/base/collections.rb', line 82

def send_or_call(duck, object)
  if duck.respond_to?(:call)
    duck.call(object)
  elsif object.respond_to? duck.to_sym
    object.send(duck)
  end
end

#send_or_call_or_object(duck, object) ⇒ Object

Avoids an issue where send_or_call can be a String and duck can be something simple like :first, which obviously String responds to.



92
93
94
95
# File 'lib/formtastic/inputs/base/collections.rb', line 92

def send_or_call_or_object(duck, object)
  return object if object.is_a?(String) # TODO what about other classes etc?
  send_or_call(duck, object)
end

#value_methodObject



10
11
12
# File 'lib/formtastic/inputs/base/collections.rb', line 10

def value_method
  label_and_value_method(raw_collection).last
end