date_select, time_select doesn’t work with auto_prefix (object[])

11 03 2009

I ran into the following issue while i was dealing with a multi-model form where a Sport is being saved with associated Events


<%= render(:partial => "event", :collection => @sport.events) %>

This partial is being rendered for collection of events for new/edit Sport

<% new_or_existing = event.new_record? ? 'new' : 'existing' %>
<% prefix = "sport[#{new_or_existing}_event_attributes][]" %>

<% fields_for prefix, event do |e| -%>
 <%= e.time_select("best_time") %>
<% end -%>

Here is the problem:

For new Event, time_select name attribute should be:   sport[new][][best_time(5i)]
but this was being assigned:   sport[new][best_time(5i)]

Following error is thrown when this form is submitted

Status: 500 Internal Server Error
Conflicting types for parameter containers. Expected an instance of Hash but found an instance of Array

For more information regarding this issue you can go through this ticket

After digging into rails code this came into light

# rails/actionpack/lib/action_view/helpers/form_helper.rb:508

if @object_name.sub!(/\[\]$/,"")
  if object ||= @template_object.instance_variable_get("@#{Regexp.last_match.pre_match}") and 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

So here @object_name would be “sport[new_event_attributes][]“
and @object_name.sub!(/\[\]$/,””) will return “sport[new_event_attributes]“
and @auto_index will set to nil

select_time internally calls option_with_prefix to assign name attribute for select element

#rails/actionpack/lib/action_view/helpers/date_helper.rb:664

def options_with_prefix(position, options)
 prefix = "#{@object_name}"
 if options[:index]
  prefix << "[#{options[:index]}]"
 elsif @auto_index
  prefix < "#{prefix}[#{@method_name}(#{position}i)]")
 end
end

Work around: pass a non nil index value along with date_select or time_select

<% new_or_existing = event.new_record? ? 'new' : 'existing' %>
<% prefix = "sport[#{new_or_existing}_event_attributes][]" %>

<% fields_for prefix, event do |e| -%>
 <%= e.time_select("best_time", :index => event.id || "") %>
<% end -%>

About these ads

Actions

Information

9 responses

15 03 2009
Michael

Perfect. I have been hitting my head against a wall with regard to Ryan’s railcast on complex forms with date_select. This fixed it perfectly. Brilliant

23 05 2009
Vincent

Brilliant, you’re a life saver. Just getting to the end of a project and got hit by this bug. Thanks!

2 06 2009
MikeInAZ

Thank you! Thank you! Thank you!

I was pulling my hair out with a similar error.

8 06 2009
Wolfram Marx

thanx a lot! just completely agree to my predecessors.
especially in the same situation as vincent.

thank you!

17 10 2009
Bobby B

Fantastic post! Thanks for this. Can I ask a further question – how were you able to capture the param sent to Rails?

*********
For new Event, time_select name attribute should be:
sport[new][][best_time(5i)]
but this was being assigned:
sport[new][best_time(5i)]
*********

I’m new to Rails and my debugging is weak. I was more embarrassed by not being able to fish this out than I was making the mistake. Any tips?

Thanks again!!

14 11 2009
Dan

I love you. This fixed my problem

27 12 2009
Krešimir Bojčić

Thanks, I was pulling my hair out over this at 02:00 AM

11 10 2012
Ganesh Kunwar

Reblogged this on Ganesh Kunwar's.

16 06 2014
tips diet sehat alami

Good answers in return of this issue with solid arguments and telling the whole thing on the topic of that.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




Follow

Get every new post delivered to your Inbox.

%d bloggers like this: