Search code examples
ruby-on-railsrubyruby-on-rails-3ruby-on-rails-4strong-parameters

Rails 3 create to Rails4 strong parameter


I was transforming my Rails 3 project to Rails4, but I am confused about strong parameter.

Here is the original code in Rails 3

series_mission = SeriesMission.create({name: params[:name], mode: Mission.mode_mapping(params[:mode].to_s), start_time: start_time, end_time: end_time, gamecharacter_id: gc.id}, :without_protection => true)

It works fine. But it's wrong after I modified into this way in Rails 4.

attrs = { name: params[:name], mode: Mission.mode_mapping(params[:mode].to_s), start_time: start_time,
     end_time: end_time, gamecharacter_id: gc.id }
attrs = attrs.require(:series_mission).permit(:name, :mode, :start_time, :end_time, :gamecharacter_id)
series_mission = SeriesMission.create(attrs)

It threw this error

private method `require' called for #<Hash:0x007fd2a421e8b8>

Update

qset_ids = params[:sub_missions]
start_time = ((t = params[:start_time].to_i) == 0 ? nil : Time.at(t))
end_time = ((t = params[:end_time].to_i) == 0 ? nil : Time.at(t))

Only gamecharacter_id is not passing by params


Solution

  • You're misunderstanding the purpose of strong parameters. They are for whitelisting incoming data. But since you already do that (by building that hash), you don't need strong params.

    attrs = { name: params[:name], mode: Mission.mode_mapping(params[:mode].to_s), start_time: start_time,
         end_time: end_time, gamecharacter_id: gc.id }
    series_mission = SeriesMission.create(attrs)
    

    What do you mean, whitelisting?

    Imagine that you have a profile edit page. There you can change a name and a picture. Some users in your app can be admins. This status is controlled by a boolean column in the db, is_admin. Naturally, you can't make user an admin through that profile edit UI, because there's no checkbox for it. However, a malicious user can forge requests however they like and send data as if there was such checkbox. And you would blindly accept it and make them admins.

    With strong params, you whitelist data you want to process

    params.require(:user).permit(:name, :picture)
    

    Here, even if is_admin param was present in the request, it would be discarded and not used in the update operation.

    As you can see, code in your question doesn't suffer from this, because there is "natural" whitelisting.