我已经用Rails编写了一个应用程序接口,需要在应用程序接口调用中接受一些nested_attributes。
目前我通过以下方式发送数据
vintages补丁/api/v1//1.json
{
"vintage": {
"year": 2014,
"name": "Some name",
"foo": "bar",
"sizes_attributes": [
{
"name": "large",
"quantity": "12"
},
{
"name": "medium",
"quantity": "2"
}
]
}
}
但是,我想执行以下操作:
vintages补丁/api/v1//1.json
{
"vintage": {
"year": 2014,
"name": "Some name",
"foo": "bar",
"sizes": [
{
"name": "large",
"quantity": "12"
},
{
"name": "medium",
"quantity": "2"
}
]
}
}
区别在于属性是字段关键字的一部分。我希望能够在不使用_attributes
的情况下将其作为JSON对象的一部分进行accept_nested_attributes_for :sizes
。
有人知道怎么处理这个问题吗?
发布于 2014-12-06 03:56:24
您可以自由地在您的强参数方法中执行一些魔术。根据您的需求,您的控制器中可能包含以下方法:
def vintage_params
params.require(:vintage).permit(:year, :name, :foo, { sizes: [:name, :quantity] })
end
您所需要做的就是在该方法中调整sizes
键的名称。我会推荐:
def vintage_params
vintage_params = params.require(:vintage).permit(:year, :name, :foo, { sizes: [:name, :quantity] })
vintage_params[:sizes_attributes] = vintage_params.delete :sizes
vintage_params.permit!
end
这将删除:sizes
密钥并将其放入预期的:sizes_attributes
中,而不会弄乱您漂亮的json。您不能直接使用accepts_nested_attributes_for
来更改名称。
发布于 2015-07-06 12:08:08
我也在寻找一种方法来避免使用嵌套属性cruft来污染我的RESTful应用程序接口。我想我应该分享我的解决方案,因为它足够通用,对遇到同样问题的任何人都很有用。它从一个简单的模块开始,该模块可以从您的控制器中利用:
module PrettyApi
class << self
def with_nested_attributes(params, attrs)
return if params.blank?
case attrs
when Hash
with_nested_hash_attributes(params, attrs)
when Array
with_nested_array_attributes(params, attrs)
when String, Symbol
unless params[attrs].blank?
params["#{attrs}_attributes"] = params.delete attrs
end
end
params
end
private
def with_nested_hash_attributes(params, attrs)
attrs.each do |k, v|
with_nested_attributes params[k], v
with_nested_attributes params, k
end
end
def with_nested_array_attributes(params, attrs)
params.each do |np|
attrs.each do |v|
with_nested_attributes np, v
end
end
end
end
end
下面是一个在控制器中使用此模块的示例,用于从移动客户端上传地址簿:
class V1::AddressBooksController < V1::BaseController
def create
@address_book = AddressBook.new address_book_params
unless @address_book.save
errors = @address_book.errors.to_hash(true)
render status: 422, json: { errors: errors }
end
end
private
def address_book_params
PrettyApi.with_nested_attributes pretty_address_book_params,
contacts: [:emails, :phones, :addresses]
end
def pretty_address_book_params
params.permit(
:device_install_id,
contacts: [
:local_id,
:first_name,
:last_name,
:nickname,
emails: [
:value,
:type
],
phones: [
:value,
:type
],
addresses: [
:type,
:street_address,
:city,
:state,
:postal_code,
:country
]
]
)
end
end
请注意,声明嵌套属性的语法反映了在控制器中声明允许的参数的语法。
Here's the Gist for this example.
我希望有人会发现这对我有帮助!
https://stackoverflow.com/questions/27260756
复制相似问题