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 -%>
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
Brilliant, you’re a life saver. Just getting to the end of a project and got hit by this bug. Thanks!
Thank you! Thank you! Thank you!
I was pulling my hair out with a similar error.
thanx a lot! just completely agree to my predecessors.
especially in the same situation as vincent.
thank you!
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!!
I love you. This fixed my problem
Thanks, I was pulling my hair out over this at 02:00 AM
Reblogged this on Ganesh Kunwar's.