aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view/helpers/form_helper.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_view/helpers/form_helper.rb')
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb99
1 files changed, 47 insertions, 52 deletions
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 0937075edf..c47fac05ef 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -293,34 +293,27 @@ module ActionView
#
# If you don't need to attach a form to a model instance, then check out
# FormTagHelper#form_tag.
- def form_for(record, record_object = nil, options = nil, &proc)
+ def form_for(record, options = nil, &proc)
raise ArgumentError, "Missing block" unless block_given?
- options, record_object = record_object, nil if record_object.is_a?(Hash)
options ||= {}
+ options[:html] ||= {}
case record
when String, Symbol
- ActiveSupport::Deprecation.warn("Using form_for(:name, @resource) is deprecated. Please use form_for(@resource, :as => :name) instead.", caller) if record_object
object_name = record
- object = record_object
- when Array
- object = record.last
- object_name = options[:as] || ActiveModel::Naming.param_key(object)
- apply_form_for_options!(record, options)
+ object = nil
else
- object = record
+ object = record.is_a?(Array) ? record.last : record
object_name = options[:as] || ActiveModel::Naming.param_key(object)
- apply_form_for_options!([object], options)
+ apply_form_for_options!(record, options)
end
- options[:html] ||= {}
options[:html][:remote] = options.delete(:remote)
-
builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc)
fields_for = fields_for(object_name, object, options, &proc)
default_options = builder.multipart? ? { :multipart => true } : {}
- output = form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html) || {}))
+ output = form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html)))
output << fields_for
output.safe_concat('</form>')
end
@@ -329,23 +322,17 @@ module ActionView
object = object_or_array.is_a?(Array) ? object_or_array.last : object_or_array
object = convert_to_model(object)
- html_options =
- if object.respond_to?(:persisted?) && object.persisted?
- { :class => options[:as] ? "#{options[:as]}_edit" : dom_class(object, :edit),
- :id => options[:as] ? "#{options[:as]}_edit" : dom_id(object, :edit),
- :method => :put }
- else
- { :class => options[:as] ? "#{options[:as]}_new" : dom_class(object, :new),
- :id => options[:as] ? "#{options[:as]}_new" : dom_id(object),
- :method => :post }
- end
+ as = options[:as]
+ action, method = object.respond_to?(:persisted?) && object.persisted? ? [:edit, :put] : [:new, :post]
+ options[:html].reverse_merge!(
+ :class => as ? "#{as}_#{action}" : dom_class(object, action),
+ :id => as ? "#{as}_#{action}" : dom_id(object, action),
+ :method => method
+ )
- options[:html] ||= {}
- options[:html].reverse_merge!(html_options)
- options[:url] ||= options[:format] ?
- polymorphic_path(object_or_array, :format => options.delete(:format)) :
- polymorphic_path(object_or_array)
+ options[:url] ||= polymorphic_path(object_or_array, :format => options.delete(:format))
end
+ private :apply_form_for_options!
# Creates a scope around a specific model object like form_for, but
# doesn't create the form tags themselves. This makes fields_for suitable
@@ -863,7 +850,7 @@ module ActionView
extend ActiveSupport::Concern
include Helpers::CaptureHelper, Context, Helpers::TagHelper, Helpers::FormTagHelper
- attr_reader :method_name, :object_name
+ attr_reader :object, :method_name, :object_name
DEFAULT_FIELD_OPTIONS = { "size" => 30 }
DEFAULT_RADIO_OPTIONS = { }
@@ -872,14 +859,9 @@ module ActionView
def initialize(object_name, method_name, template_object, object = nil)
@object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
@template_object = template_object
- @object = object
- if @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]")
- if (object ||= @template_object.instance_variable_get("@#{Regexp.last_match.pre_match}")) && object.respond_to?(:to_param)
- @auto_index = object.to_param
- else
- raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
- end
- end
+ @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]")
+ @object = retrieve_object(object)
+ @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match
end
def to_label_tag(text = nil, options = {}, &block)
@@ -1003,14 +985,26 @@ module ActionView
content_tag(tag_name, value(object), options)
end
- def object
- @object || @template_object.instance_variable_get("@#{@object_name}")
+ def retrieve_object(object)
+ if object
+ object
+ elsif @template_object.instance_variable_defined?("@#{@object_name}")
+ @template_object.instance_variable_get("@#{@object_name}")
+ end
rescue NameError
- # As @object_name may contain the nested syntax (item[subobject]) we
- # need to fallback to nil.
+ # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil.
nil
end
+ def retrieve_autoindex(pre_match)
+ object = self.object || @template_object.instance_variable_get("@#{pre_match}")
+ if object && object.respond_to?(:to_param)
+ object.to_param
+ else
+ raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
+ end
+ end
+
def value(object)
self.class.value(object, @method_name)
end
@@ -1183,17 +1177,14 @@ module ActionView
if nested_attributes_association?(record_or_name_or_array)
return fields_for_with_nested_attributes(record_or_name_or_array, args, block)
else
- name = "#{object_name}#{index}[#{record_or_name_or_array}]"
+ name = record_or_name_or_array
end
- when Array
- object = record_or_name_or_array.last
- name = "#{object_name}#{index}[#{ActiveModel::Naming.param_key(object)}]"
- args.unshift(object)
else
- object = record_or_name_or_array
- name = "#{object_name}#{index}[#{ActiveModel::Naming.param_key(object)}]"
+ object = record_or_name_or_array.is_a?(Array) ? record_or_name_or_array.last : record_or_name_or_array
+ name = ActiveModel::Naming.param_key(object)
args.unshift(object)
end
+ name = "#{object_name}#{index}[#{name}]"
@template.fields_for(name, *args, &block)
end
@@ -1253,7 +1244,7 @@ module ActionView
end
def emitted_hidden_id?
- @emitted_hidden_id
+ @emitted_hidden_id ||= nil
end
private
@@ -1262,7 +1253,7 @@ module ActionView
end
def submit_default_value
- object = @object.respond_to?(:to_model) ? @object.to_model : @object
+ object = convert_to_model(@object)
key = object ? (object.persisted? ? :update : :create) : :submit
model = if object.class.respond_to?(:model_name)
@@ -1287,7 +1278,7 @@ module ActionView
name = "#{object_name}[#{association_name}_attributes]"
options = args.extract_options!
association = args.shift
- association = association.to_model if association.respond_to?(:to_model)
+ association = convert_to_model(association)
if association.respond_to?(:persisted?)
association = [association] if @object.send(association_name).is_a?(Array)
@@ -1308,7 +1299,7 @@ module ActionView
end
def fields_for_nested_model(name, object, options, block)
- object = object.to_model if object.respond_to?(:to_model)
+ object = convert_to_model(object)
if object.persisted?
@template.fields_for(name, object, options) do |builder|
@@ -1324,6 +1315,10 @@ module ActionView
@nested_child_index[name] ||= -1
@nested_child_index[name] += 1
end
+
+ def convert_to_model(object)
+ object.respond_to?(:to_model) ? object.to_model : object
+ end
end
end