[英]How to accept JSON through Rails API without “_attributes” for nested fields
我用Rails編寫了一個API,需要在API調用中接受一些nested_attributes。
目前我通過發送數據
PATCH /api/v1/vintages/1.json
{
"vintage": {
"year": 2014,
"name": "Some name",
"foo": "bar",
"sizes_attributes": [
{
"name": "large",
"quantity": "12"
},
{
"name": "medium",
"quantity": "2"
}
]
}
}
但是,我想執行以下操作:
PATCH /api/v1/vintages/1.json
{
"vintage": {
"year": 2014,
"name": "Some name",
"foo": "bar",
"sizes": [
{
"name": "large",
"quantity": "12"
},
{
"name": "medium",
"quantity": "2"
}
]
}
}
區別在於屬性是字段鍵的一部分。 我希望能夠accept_nested_attributes_for :sizes
而不必使用_attributes
作為JSON對象的一部分。
誰知道如何管理這個?
您可以自由地在強參數方法中執行一些魔術。 根據您的需要,您可能在控制器中使用此方法:
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
更改名稱。
我也在尋找一種方法來避免使用嵌套屬性cruft污染我的RESTful API。 我以為我會分享我的解決方案,因為它足以對遇到同樣問題的人有用。 它首先從您的控制器中利用一個簡單的模塊:
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
請注意,聲明嵌套屬性的語法反映了在控制器中聲明允許的參數的語法。
我希望有人覺得這很有用!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.