Rails 4 Strong parameters with JSON array

2019-09-02 10:02发布

I am trying to post an array of JSON objects, but i always get a 422 Unprocessable Entity response.
This is my controller action:

def create
 @myusers = params[:user]
 @myusers.each do
 User.create(user_params)
end     

def user_params
             params.permit(:name,:address )
end

Where,together with the below shown http call, the @myuser array looks like this

@myuser =[{"name"=>"name11", "address"=>"addr1"}, {"name"=>"name22", "address"=>"addr2"}, {"name"=>"name33", "address"=>"addr132"}, {"name"=>"name4", "address"=>"addr4"}]

This is the HTTP JSON body

{"user":[{
   "name" : "name11",
   "address":"addr1"
},
{
    "name" : "name22",
    "address":"addr2"
},
{
    "name" : "name33",
    "address":"addr132"
},
{
    "name" : "name4",
    "address":"addr4"
}
]}

and i added the Accept/Content-Type : application/json header. The log file shows this

Started POST "/api/customer/" for 127.0.0.1 at 2015-11-02 18:45:09 +0100
Processing by Api::UserController#create as JSON
Parameters: {"user"=>[{"name"=>"name11", "address"=>"addr1"},  {"name"=>"name22", "address"=>"addr2"}, {"name"=>"name33", "address"=>"addr132"}, {"name"=>"name4", "address"=>"addr4"}]}
Unpermitted parameters: customer, format
   (0.4ms)  BEGIN
   (0.3ms)  ROLLBACK
Unpermitted parameters: customer, format
   (0.3ms)  BEGIN
   (0.3ms)  ROLLBACK
Unpermitted parameters: customer, format
   (0.2ms)  BEGIN
   (0.6ms)  ROLLBACK
Unpermitted parameters: customer, format
   (0.3ms)  BEGIN
   (0.4ms)  ROLLBACK
Unpermitted parameters: customer, format
   (0.3ms)  BEGIN
   (0.4ms)  ROLLBACK
Completed 422 Unprocessable Entity in 62ms (Views: 0.6ms | ActiveRecord: 7.0ms)

Each of the single objects is an ApplicationControllerParameter so it should be possible to call directly the user_params action for each entry? Or am i wrong there?

thanks in advance for your help.

Solution:

I think there s some possibility that this code can be done a bit more nice but this is now working for me:

  def user_params
         params.permit(user: [:name,:address])
  end

  def create 
         user_params[:user].each do |u|
             User.create(u)
         end
  end

2条回答
可以哭但决不认输i
2楼-- · 2019-09-02 10:48

Your issue as far as the question about parameters is concerned is that you're using the whole params hash and not narrowing it down to the 'user' bit that you're interested in permitting. So you're getting all the other stuff that's passed e.g. format. (Incidentally, shouldn't it more correctly be called 'users' rather than the singular 'user'? Anyway... Never mind that :)

I think it should be something like

params.permit(user: [:name, :address])

or

params.require(:user).permit?([:name, :address])

There's a bit about nested parameters in the docs of the strong_parameters gem here:

https://github.com/rails/strong_parameters#nested-parameters

Hope that helps...

查看更多
小情绪 Triste *
3楼-- · 2019-09-02 10:54

So, you have an array of hashes coming through params, which needed to be permitted, and then you do a simple loop over your array to save each to your database.

The first step is getting the params permission right.

You can check the documentation here for more insight into permitting params.

Let's define the users_params private method as follow:

def users_params
  params.permit(user: []) #declare that the parameter should be an array of permitted scalars by mapping it to an empty array
end

Then from the create action:

def create
  @myusers = users_params #this returns an array of the user hashes passed from params
  # Now, loop through these hashes, and create new users with their values
  @myusers.each do |user_hash| 
    User.create(user_hash)
  end
end

Note that we are not repeatedly going to fetch the JSON hashes from the params. Since we already have it all in our @myusers variable, all that is needed to do is to loop through it, and save a new instance of User with the hash at the current index of our loop.

More examples on how to permit different types of params are available in the above documentation, you can check it out as well.

Hope this was helpful

查看更多
登录 后发表回答