我正在构建一个rails4 api,在其中发布一个嵌套的属性哈希。然而,该模型实际上并没有嵌套的属性或关联。试图通过将一些属性组合成一个组来制作一个更干净的post-params哈希,但要让api处理展开和强参数验证。
## Example POST params
params[:item][:group] = {
a: true,
b: false
}
但是模型实际上没有group
列,属性a
和b
是直接在模型上的属性。
要在没有group
包装的情况下处理此问题,只需
params.require(:item).permit(:a, :b)
但我想让它通过strong_parameters
和group
包装一起提交。如果没有上面提到的POST参数,我该如何实现这一点?
您可以在调用操作之前剥离所有中间级别:
class YourController < ApplicationController
before_action :flatten_item_params
private
def flatten_item_params
params[:item] = params.require(:item).each_with_object({}) do |(key, value), result|
result.merge!(value)
end
end
def item_params
params[:item].permit(:a, :b)
end
end
关于"嵌套"参数的传递,文档非常明确;按照Hoang Phan
的建议,您可以将嵌套哈希传递给您的控制器:
params: {
object: {
title: "Test",
group: {
a: "test",
b: "test"
}
}
}
这可以通过以下方式接受:
def params
params.require(:object).permit(:title, group: [:a, :b])
end
--
这方面的问题是,我认为所有密钥都必须存在于模型中。要解决此问题,可以使用virtual attribute
:
#app/models/your_model.rb
class YourModel < ActiveRecord::Base
attr_accessor :group, :a, :b
end
虚拟属性不保存,而是附加到类的实例方法,允许您用不需要放入数据库的数据填充它。
使用上面的应该使您能够使用嵌套的params哈希;唯一的缺点是必须坚持使用group: [:a, :b]
作为params的结构。
与大多数ruby/rails情况一样,可能有更好的方法来实现这一点。从这些回复中,我最终采用了这种看似黑客的方法。重要的是,它能满足我的需求,但感觉很恶心,所以如果有人有更优雅的方式,请分享!
class YourController < ApplicationController
private
## POST { item: { group: { a: true, b: false } } }
def item_params
group = params[:item][:group].presence
if group
## Unwrap nesting and place at root of params[:item]
## Probably should explicitly handle this instead of iterating
group.each {|k,v| params[:item][k] = v }
params[:item].delete :group
end
params[:item].permit(:a, :b)
end
end