lib/formtastic/inputs/base/collections.rb in formtastic-2.0.0.rc5 vs lib/formtastic/inputs/base/collections.rb in formtastic-2.0.0
- old
+ new
@@ -1,101 +1,100 @@
module Formtastic
module Inputs
module Base
module Collections
-
+
def label_method
label_and_value_method(raw_collection).first
end
-
+
def value_method
label_and_value_method(raw_collection).last
end
-
+
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
-
+
def raw_collection
@raw_collection ||= (collection_from_options || collection_from_association || collection_for_boolean)
end
-
+
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
-
+
def collection_from_options
items = options[:collection]
items = items.to_a if items.is_a?(Hash)
items
end
-
+
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.where(
- conditions_from_reflection.merge(conditions_from_options)
- )
+ 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.where(conditions_from_reflection.merge(find_options_from_options))
+ reflection.klass.scoped(:conditions => conditions_from_reflection).where(find_options_from_options)
end
end
end
-
+
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
-
+
def send_or_call(duck, object)
if duck.respond_to?(:call)
duck.call(object)
- else
+ elsif object.respond_to? duck.to_sym
object.send(duck)
end
end
-
+
# Avoids an issue where `send_or_call` can be a String and duck can be something simple like
# `:first`, which obviously String responds to.
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
-
+
end
end
end
end