如何允许使用rails强参数进行哈希



我正在开发一个名为element的atter_accessor对象的Model。我想将表单数据的数组传递给元素对象。在Rails控制台中,我得到了Unpermited参数错误。

Parameters: {"authenticity_token"=>"[FILTERED]", "category"=>{"name"=>"asfd", "body"=>"asf", "element"=>{"1"=>"asfd:text", "2"=>"asfd:text", "3"=>"asfd:text"}}, "type"=>"text", "commit"=>"Create Category"}
Unpermitted parameter: :element. Context: { controller: CategoriesController, action: create, request: #<ActionDispatch::Request:0x0000000106b3ff68>, params: {"authenticity_token"=>"[FILTERED]", "category"=>{"name"=>"asfd", "body"=>"asf", "element"=>{"1"=>"asfd:text", "2"=>"asfd:text", "3"=>"asfd:text"}}, "type"=>"text", "commit"=>"Create Category", "controller"=>"categories", "action"=>"create"} }

在模型中attr_accessor :elements

在控制器中

def category_params
params.require(:category).permit(:name, :body, :elements => []) 
end

我也尝试了许多将:elements更改为element: []的替代方案,但都没有成功。我想我在这里错过了一些东西,这就是我得到一个不允许的参数的原因。

您还没有提到您正在使用的rails的版本,但是,:elements => []不起作用,因为元素是ruby哈希而不是数组

在轨道5.1+上,您可以使用

params.require(:category).permit(:name, :body, :elements => {}) 

除了element/elements命名问题之外,这里还有很多困惑——选择一个并坚持下去。

如果您想在机架应用程序中将数组作为FormData传递,则需要使用带空括号的密钥:

irb(main):001:0> str = "elements[]=a&elements[]=b&elements[]=c"                                                         => "elements[]=a&elements[]=b&elements[]=b"
irb(main):002:0> Rack::Utils.parse_nested_query(str)                                                                   
=> {"elements"=>["a", "b", "c"]}   

如果您在括号中放置任何类型的值,它将被解析为哈希:

irb(main):003:0> str = "elements[1]=a&elements[2]=b&elements[3]=c"
=> "elements[1]=a&elements[2]=b&elements[3]=b"
irb(main):004:0> Rack::Utils.parse_nested_query(str)
=> {"elements"=>{"1"=>"a", "2"=>"b", "3"=>"c"}}    

当将空数组列入白名单时,将允许使用允许的标量值数组:

irb(main):005:0> params = ActionController::Parameters.new(Rack::Utils.parse_nested_query("elements[]=a&elements[]=b&elements[]=b"))
=> #<ActionController::Parameters {"elements"=>["a", "b", "b"]} permitted: false>
irb(main):006:0> params.permit(elements: [])
=> #<ActionController::Parameters {"elements"=>["a", "b", "b"]} permitted: true> 

当白名单散列时,你会传递一组符号,这些符号代表你想要允许的密钥:

irb(main):006:0> params = ActionController::Parameters.new(foo: { bar: 1, baz: 2, woo: 3 })
irb(main):007:0> params.permit(foo: [:bar, :baz])
=> #<ActionController::Parameters {"foo"=>#<ActionController::Parameters {"bar"=>1, "baz"=>2} permitted: true>} permitted: true>

您还可以通过传递一个空散列来允许使用任意密钥的散列:

irb(main):008:0> params.permit(foo: {})
=> #<ActionController::Parameters {"foo"=>#<ActionController::Parameters {"bar"=>1, "baz"=>2, "woo"=>3} permitted: true>} permitted: true>  

这是一个有点危险的操作,应该小心操作。

最新更新