Rails 4允许嵌套属性不创建/更新

时间:2021-12-27 01:16:22

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.

我将我的rails应用程序(-v3.2.13)转换为rails 4.I使用继承资源gem的覆盖操作(创建!并更新!)。我允许参数的整个哈希值,但它不会创建/更新嵌套属性。我需要允许参数的整个哈希。当我尝试时,我收到以下错误。帮我解决这个问题。

params

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

Foo模型

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>'

7 个解决方案

#1


6  

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

我遇到了类似的问题。尝试执行以下操作。假设你需要更新foo1。将此用于您的强参数。

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

#2


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:

在执行此操作时,请记住链接的README文档中的以下引用:

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

使用许可证时应格外小心!因为它将允许所有当前和未来的模型属性进行质量分配。

#3


4  

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 ] )

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.

它可以解决您的问题。

#4


3  

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

使用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:

这里其他答案的问题是它们没有考虑到foo1_attributes的值有一个数组:

(expanded example from OP)

(来自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]

因此,您需要同时允许foo1_attributes和foo1_attributes [n]

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

以下是我在项目中成功实现类似功能的方法:

(formated to OP's exmaple above)

(形成OP以上的例子)

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...

其他一些注意事项......

#5


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

更多信息:https://github.com/josevalim/inherited_resources#strong-parameters

#6


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.

我相信你的resource_params方法应该被称为allowed_pa​​rams。有关如何处理强参数的更多详细信息,请参阅“继承的资源”文档。

#7


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.

我不认为这是一个强大的参数相关错误。在Rails 4.0中,如果参数未列入白名单,则会以静默方式失败并且不会创建对象。我有一段时间没有这个错误,我不知道如何修复它,但是你可以发布你的routes.rb文件,并在你的控制器中包含new和create方法吗?我很确定你的错误在你的资源嵌套中。

#1


6  

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

我遇到了类似的问题。尝试执行以下操作。假设你需要更新foo1。将此用于您的强参数。

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

#2


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:

在执行此操作时,请记住链接的README文档中的以下引用:

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

使用许可证时应格外小心!因为它将允许所有当前和未来的模型属性进行质量分配。

#3


4  

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 ] )

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.

它可以解决您的问题。

#4


3  

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

使用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:

这里其他答案的问题是它们没有考虑到foo1_attributes的值有一个数组:

(expanded example from OP)

(来自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]

因此,您需要同时允许foo1_attributes和foo1_attributes [n]

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

以下是我在项目中成功实现类似功能的方法:

(formated to OP's exmaple above)

(形成OP以上的例子)

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...

其他一些注意事项......

#5


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

更多信息:https://github.com/josevalim/inherited_resources#strong-parameters

#6


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.

我相信你的resource_params方法应该被称为allowed_pa​​rams。有关如何处理强参数的更多详细信息,请参阅“继承的资源”文档。

#7


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.

我不认为这是一个强大的参数相关错误。在Rails 4.0中,如果参数未列入白名单,则会以静默方式失败并且不会创建对象。我有一段时间没有这个错误,我不知道如何修复它,但是你可以发布你的routes.rb文件,并在你的控制器中包含new和create方法吗?我很确定你的错误在你的资源嵌套中。