11

I convert my rails app(-v3.2.13) to rails 4.I use inherited resources gem's overwriting actions(create! and update!).I permit entire hash of the parameters,But It doesn't create/update the nested attributes.I need to permit the entire hash of the parameters.When i tried, i am getting the following error.Help me to solve this.

params

{"foo"=>{"name"=>"1@1", "detail"=>"123", foo1_attributes"=>{"0"=>{"_destroy"=>"", "name"=>"John", "url"=>"johnsmith.blogspot.com",foo2_attributes"=>{"0"=>{"min_time"=>"0", "max_entry"=>"340"}}, "foo3_attributes"=>{"_destroy"=>"", "hours"=>"01", "minutes"=>"00"}, "status"=>"ACTIVE"}}, "foo4_attributes"=>{"0"=>{"image"=>"0","id"=>"1097"}}}, "commit"=>"Save", "foo_id"=>"13", "id"=>"1467"}

My controller

def update
 update! do |success, failure|
  success.html { redirect_to foo_path }
 end
end

protected

def resource_params
 params.permit!
end

Foo Model

accepts_nested_attributes_for : foo1,foo2,foo3,foo4
has_many :foo1
has_many :foo2
has_many :foo3
has_many :foo4

Trace:

 Completed 500 Internal Server Error in 3686ms

 ArgumentError (wrong number of arguments (6 for 1..2)):
  app/controllers/foo_controller.rb:160:in `update'

 protected_attributes (1.0.3) lib/active_record/mass_assignment_security/persistence.rb:60:in `update_attributes'
inherited_resources (1.3.1) lib/inherited_resources/base_helpers.rb:78:in `update_resource'
inherited_resources (1.3.1) lib/inherited_resources/actions.rb:45:in `update'
app/controllers/partner_modules_controller.rb:160:in `update'
actionpack (4.0.0) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
actionpack (4.0.0) lib/abstract_controller/base.rb:189:in `process_action'
actionpack (4.0.0) lib/action_controller/metal/rendering.rb:10:in `process_action'
actionpack (4.0.0) lib/abstract_controller/callbacks.rb:18:in `block in process_action'
activesupport (4.0.0) lib/active_support/callbacks.rb:445:in `block (2 levels) in _run__2668227825050344147__process_action__callbacks'
activesupport (4.0.0) lib/active_support/callbacks.rb:212:in `block in _conditional_callback_around_4134'
rails-observers (0.1.2) lib/rails/observers/action_controller/caching/sweeping.rb:73:in `around'
activesupport (4.0.0) lib/active_support/callbacks.rb:283:in `_callback_around_4133'
activesupport (4.0.0) lib/active_support/callbacks.rb:211:in `_conditional_callback_around_4134'
activesupport (4.0.0) lib/active_support/callbacks.rb:444:in `block in _run__2668227825050344147__process_action__callbacks'
activesupport (4.0.0) lib/active_support/callbacks.rb:215:in `_conditional_callback_around_4135'
activesupport (4.0.0) lib/active_support/callbacks.rb:443:in `_run__2668227825050344147__process_action__callbacks'
activesupport (4.0.0) lib/active_support/callbacks.rb:80:in `run_callbacks'
actionpack (4.0.0) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (4.0.0) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
activesupport (4.0.0) lib/active_support/notifications.rb:159:in `block in instrument'
activesupport (4.0.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.0.0) lib/active_support/notifications.rb:159:in `instrument'
actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
actionpack (4.0.0) lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
activerecord (4.0.0) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (4.0.0) lib/abstract_controller/base.rb:136:in `process'
actionpack (4.0.0) lib/abstract_controller/rendering.rb:44:in `process'
actionpack (4.0.0) lib/action_controller/metal.rb:195:in `dispatch'
actionpack (4.0.0) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
actionpack (4.0.0) lib/action_controller/metal.rb:231:in `block in action'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:80:in `call'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:80:in `dispatch'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:48:in `call'
actionpack (4.0.0) lib/action_dispatch/journey/router.rb:71:in `block in call'
actionpack (4.0.0) lib/action_dispatch/journey/router.rb:59:in `each'
actionpack (4.0.0) lib/action_dispatch/journey/router.rb:59:in `call'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:655:in `call'
newrelic_rpm (3.6.6.147) lib/new_relic/rack/error_collector.rb:43:in `call'
bullet (4.6.0) lib/bullet/rack.rb:13:in `call'
newrelic_rpm (3.6.6.147) lib/new_relic/rack/error_collector.rb:43:in `call'
newrelic_rpm (3.6.6.147) lib/new_relic/rack/agent_hooks.rb:22:in `call'
newrelic_rpm (3.6.6.147) lib/new_relic/rack/browser_monitoring.rb:16:in `call'
warden (1.2.3) lib/warden/manager.rb:35:in `block in call'
warden (1.2.3) lib/warden/manager.rb:34:in `catch'
warden (1.2.3) lib/warden/manager.rb:34:in `call'
rack (1.5.2) lib/rack/etag.rb:23:in `call'
rack (1.5.2) lib/rack/conditionalget.rb:35:in `call'
rack (1.5.2) lib/rack/head.rb:11:in `call'
remotipart (1.2.1) lib/remotipart/middleware.rb:27:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/flash.rb:241:in `call'
rack (1.5.2) lib/rack/session/abstract/id.rb:225:in `context'
rack (1.5.2) lib/rack/session/abstract/id.rb:220:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/cookies.rb:486:in `call'
activerecord (4.0.0) lib/active_record/query_cache.rb:36:in `call'
activerecord (4.0.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:626:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.0.0) lib/active_support/callbacks.rb:373:in `_run__994999873434308059__call__callbacks'
activesupport (4.0.0) lib/active_support/callbacks.rb:80:in `run_callbacks'
actionpack (4.0.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/reloader.rb:64:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.0.0) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.0.0) lib/rails/rack/logger.rb:21:in `block in call'
activesupport (4.0.0) lib/active_support/tagged_logging.rb:67:in `block in tagged'
activesupport (4.0.0) lib/active_support/tagged_logging.rb:25:in `tagged'
activesupport (4.0.0) lib/active_support/tagged_logging.rb:67:in `tagged'
railties (4.0.0) lib/rails/rack/logger.rb:21:in `call'
quiet_assets (1.0.2) lib/quiet_assets.rb:18:in `call_with_quiet_assets'
actionpack (4.0.0) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
rack (1.5.2) lib/rack/runtime.rb:17:in `call'
rack (1.5.2) lib/rack/lock.rb:17:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/static.rb:64:in `call'
railties (4.0.0) lib/rails/engine.rb:511:in `call'
railties (4.0.0) lib/rails/application.rb:97:in `call'
rack (1.5.2) lib/rack/content_length.rb:14:in `call'
thin (1.5.1) lib/thin/connection.rb:81:in `block in pre_process'
thin (1.5.1) lib/thin/connection.rb:79:in `catch'
thin (1.5.1) lib/thin/connection.rb:79:in `pre_process'
thin (1.5.1) lib/thin/connection.rb:54:in `process'
thin (1.5.1) lib/thin/connection.rb:39:in `receive_data'
eventmachine (1.0.3) lib/eventmachine.rb:187:in `run_machine'
eventmachine (1.0.3) lib/eventmachine.rb:187:in `run'
thin (1.5.1) lib/thin/backends/base.rb:63:in `start'
thin (1.5.1) lib/thin/server.rb:159:in `start'
rack (1.5.2) lib/rack/handler/thin.rb:16:in `run'
rack (1.5.2) lib/rack/server.rb:264:in `start'
railties (4.0.0) lib/rails/commands/server.rb:84:in `start'
railties (4.0.0) lib/rails/commands.rb:78:in `block in <top (required)>'
railties (4.0.0) lib/rails/commands.rb:73:in `tap'
railties (4.0.0) lib/rails/commands.rb:73:in `<top (required)>'
script/rails:6:in `require'
script/rails:6:in `<main>'
Mano
  • 979
  • 1
  • 18
  • 36
  • `params.require(:foo).permit(:attr_of_foo, :another_attr_of_foo, :foo1_attributes => [:attr_of_foo1, :more_attr_of_foo1], ..so forth)` doesn't work for you? – j03w Aug 19 '13 at 05:37
  • @jo3w Yes,I tried with `params.requir(:foo).permit(:name,:detail,foo1_attributes: [:name, :url])`,But i am getting wrong number of arguments error.I need to permit the entire hash.Am i missing anything here? – Mano Aug 19 '13 at 06:59
  • 1
    Possible duplicate of http://stackoverflow.com/questions/17371334/how-is-attr-accessible-used-in-rails-4/17371364#17371364 – Pierre-Louis Gottfrois Aug 20 '13 at 05:50

7 Answers7

6

I faced a similiar kind of problem. Try doing the following. Assuming you need to update foo1. Use this for your strong parameters.

def foo_params
  params.require(:foo).permit(:foo1_attributes => [:bar1 , :bar2])
end

Do update by.

def update  
  if @foo.update_attributes!(foo_params)      
    redirect_to foo_path
  else
    render foo1_edit_path
  end
end
Bryan Ash
  • 4,385
  • 3
  • 41
  • 57
xvidun
  • 477
  • 5
  • 12
5

hi you must use it this way:

params.require( :foo ).permit( :name, :details, foo1_attributes: [ :_destroy, :name, :url, :id ], foo2_attributes: [ :_destroy, :min_time, :max_entry, :id ] )

It may solve your problem.

xaph
  • 663
  • 5
  • 15
Akshat
  • 615
  • 7
  • 18
  • 1
    here remember that id of nested attributes is not needed in case of creation but it is compulsary while updating nested attributes otherwise it will create a new copy of it for you. Thats why i added id field in nested attributes permit fields – Akshat Nov 04 '13 at 07:22
4

As stated in the Strong Parameters README, you can use the permit! method to whitelist the entire hash of parameters as follows:

params.require(:foo).permit!

Please keep in mind the following quote from the README document linked when doing this:

Extreme care should be taken when using permit! as it will allow all current and future model attributes to be mass-assigned.

vee
  • 38,255
  • 7
  • 74
  • 78
  • It doesn't work.Still i am getting wrong number of aruguments error. – Mano Aug 19 '13 at 07:48
  • Can you post the full trace in your question when this error occurs. – vee Aug 19 '13 at 07:49
  • @Mano, is that it? There should be more because I don't see the error you are talking about. – vee Aug 19 '13 at 09:32
  • 2
    @Mano, Please try calling `update!` with `resource_params` parameter, i.e. in your update action do `update!(resource_params) do |success, failure|` – vee Aug 19 '13 at 10:02
  • Oh my god thank you! I have been writing endless permit(.....) calls on totally non-critical models for far too long. I didn't know this was so easy! – Tigraine May 19 '15 at 08:37
4

This may be a bit late, but I just faced this myself. Hopefully it will save someone else some time.

Using Rails 4.2.1

The problem with the other answers here is that they don't take into consideration that there is an array for the value of foo1_attributes:

(expanded example from OP)

foo1_attributes"=> {
  "0"=> {
     "_destroy"=>"", "name"=>"John", "url"=>"johnsmith.blogspot.com"
  }
}

Because of this, you need to permit both foo1_attributes and foo1_attributes[n]

Here is how I successfully implimented similar functionality in my project:

(formated to OP's exmaple above)

def resource_params
  params.require(:foo)
    .permit(
      :id,
      :name,
      :detail,

      # has_many: :foo1s (Nested Attributes)
        { foo1_attributes: [
          # and the values for each `foo1` in `foo1_attributes`
          [
            :name,
            :url
          ]
        ]},

      # has_many: :foo2s (Nested Attributes)
        { foo2_attributes: [
          # and the values for each `foo2` in `foo2_attributes`
          [
            :min_time,
            :max_entry
          ]
        ]}

      # etc...
    )

Some other things to note...

Community
  • 1
  • 1
Eric Norcross
  • 4,177
  • 4
  • 28
  • 53
1

Replace your current strong params with this:

def permitted_params
    params.permit(:widget => [:permitted_field, :other_permitted_field])
end

More info: https://github.com/josevalim/inherited_resources#strong-parameters

Richard Peck
  • 76,116
  • 9
  • 93
  • 147
0

I believe your resource_params method should be called permitted_params. More details on how to handle strong parameters are in the Inherited Resources documentation.

Chris Fritz
  • 1,922
  • 1
  • 19
  • 23
0

I don't think this is a strong parameter related error. In Rails 4.0, if a parameter is not whitelisted, it fails silently and the object is not created. I had this error a while back and I don't exactly how to fix it, but can you post your routes.rb file, and include the new and create methods in your controller? I'm pretty sure your error is in your resource nesting.

Michael Choi
  • 134
  • 1
  • 10