expected Hash (got Array) for param 'samples'
Asked Answered
G

4

10

I have been following Railscasts episodes of Nested forms and complex forms. During the time of creating multiple model in a single form I was able to edit, update, delete and create records for sample models that were nested in the Batch model.

I have been breaking my head from a long time and tried searching around as well but could not get any right solution for solving this problem.

my development log file gives me the following error.

ERROR MESSAGE:

Status: 500 Internal Server Error
  expected Hash (got Array) for param `samples'

in my controller I have the update action like this

def update
     @batch = Batch.find(params[:id])

     respond_to do |format|
       if @batch.update_attributes(params[:batch])
         flash[:notice] = 'Successfully updated Batch.'
         format.html { redirect_to(@batch) }
         format.xml  { head :ok }
       else
         format.html { render :action => "edit" }
         format.xml  { render :xml => @batch.errors, :status => :unprocessable_entity }
       end
     end
   end

my view is something like this:

<%= form_for @batch do |f| %>
......
<%= f.fields_for :samples do |s_form| %>
.... s_form things
<% end %>
<% end %>

my model contains the same stuff :

has_many :samples, :dependent => :destroy

  accepts_nested_attributes_for :samples, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true

All suggestions are appreciated.

Gavra answered 13/2, 2012 at 10:52 Comment(2)
I ran into a similar problem when using text_field_tag in my form because I supplied Rails-2-style args when I was running Rails 3. Do you see yourself doing that at all? If not, can you provide the entirety of your view? (maybe on pastie.org)Parasiticide
I ran into this error message when the array of strings contained some null elements.Crusade
C
18

for others who met the same problem:

this error is caused when you have two fields in your form like:

video: 'some string'
video['url']:  'some url'

then rails will crash with the error: expected Hash (got String) for param

the solution is quite simple: change 'video' to something else. e.g.:

video_origin_url: 'some string'
video['url']: 'some url'
Creosol answered 8/10, 2013 at 11:36 Comment(1)
This is very helpful. It feels odd to me that rails 3.2 doesn't have a more descriptive error for this.Arnettaarnette
B
4

I had the same problem, and just fixed it.

Check the headers of your request. I mine I saw:

weight[2][name]:Tests
weight[2][value]:75
weight[1][name]:Quizzes
weight[1][value]:25
weight[][name]:Foo
weight[][value]:

It was the last two which caused the issue. In my case I had to give this weight an ID to get rid of the error.

Bartlet answered 8/10, 2012 at 11:50 Comment(0)
D
0

I also got this error Invalid request parameters: expected Hash (got Array) for param 'cell'.

In my case, I misformed the field name like

f.text_field :name, name: 'cell[name][]'

this was causing the error. Now I did the following and the error is gone:-

f.text_field :name, name: 'cell[][name]'

in this solution I was actually trying to get data in array format.

Dissemblance answered 17/12, 2019 at 4:28 Comment(0)
H
0

I had this problem, when the user typed the params himself in the request like:

https://example.com/page?samples[]=1&samples[test]=2

Debugging the code, I got down to a Rack::QueryParser.parse_nested_query method in the rack gem:

# parse_nested_query expands a query string into structural types. Supported
# types are Arrays, Hashes and basic value types. It is possible to supply
# query strings with parameters of conflicting types, in this case a
# ParameterTypeError is raised. Users are encouraged to return a 400 in this
# case.
def parse_nested_query(qs, d = nil)
  params = make_params

  unless qs.nil? || qs.empty?
    (qs || '').split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
      k, v = p.split('=', 2).map! { |s| unescape(s) }

      normalize_params(params, k, v, param_depth_limit)
    end
  end

  return params.to_h
rescue ArgumentError => e
  raise InvalidParameterError, e.message, e.backtrace
end

From the docstring:

It is possible to supply query strings with parameters of conflicting types, in this case a ParameterTypeError is raised. Users are encouraged to return a 400 in this case.

I found few solutions here Rails ActionController::BadRequest causes 500 Server Error on production server

Heterocercal answered 16/1, 2023 at 10:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.