处理JSON时如何使用nested_attributes?
How to use nested_attributes when processing JSON?
我正在尝试编写一个处理 JSON 的更新方法。 JSON 看起来像这样:
{
"organization": {
"id": 1,
"nodes": [
{
"id": 1,
"title": "Hello",
"description": "My description."
},
{
"id": 101,
"title": "fdhgh",
"description": "My description."
}
]
}
}
组织模型:
has_many :nodes
accepts_nested_attributes_for :nodes, reject_if: :new_record?
组织序列化程序:
attributes :id
has_many :nodes
节点序列化器:
attributes :id, :title, :description
组织控制器中的更新方法:
def update
organization = Organization.find(params[:id])
if organization.update_attributes(nodes_attributes: node_params.except(:id))
render json: organization, status: :ok
else
render json: organization, status: :failed
end
end
private
def node_params
params.require(:organization).permit(nodes: [:id, :title, :description])
end
我还尝试将 accepts_nested_attributes_for
添加到组织 serializer,但这似乎不正确,因为它产生了错误 (undefined method 'accepts_nested_attributes_for'
),所以我只将 accepts_nested_attributes_for
添加到模型而不是序列化程序。
上面的代码生成下面的错误,参考更新方法中的 update_attributes
行。我做错了什么?
no implicit conversion of String into Integer
在调试器中 node_params
returns:
Unpermitted parameters: id
{"nodes"=>[{"id"=>101, "title"=>"gsdgdsfgsdg.", "description"=>"dgdsfgd."}, {"id"=>1, "title"=>"ertret.", "description"=>"etewtete."}]}
更新: 使用以下命令使其工作:
def update
organization = Organization.find(params[:id])
if organization.update_attributes(nodes_params)
render json: organization, status: :ok
else
render json: organization, status: :failed
end
end
private
def node_params
params.require(:organization).permit(:id, nodes_attributes: [:id, :title, :description])
end
我向序列化程序添加了 root: :nodes_attributes
。
现在一切正常,但是 我担心在 node_params
中包含 ID。这样安全吗? 现在难道不能编辑 organization
和 node
的 ID(这是不允许的)吗? 以下是否是不允许它更新 id 的正确解决方案:
if organization.update_attributes(nodes_params.except(:id, nodes_attributes: [:id]))
看起来超级接近。
您的 json 子对象 'nodes' 需要 'nodes_attributes'。
{
"organization": {
"id": 1,
"nodes_attributes": [
{
"id": 1,
"title": "Hello",
"description": "My description."
},
{
"id": 101,
"title": "fdhgh",
"description": "My description."
}
]
}
}
你可以做这种事。将其放入您的控制器中。
before_action do
if params[:organization]
params[:organization][:nodes_attributes] ||= params[:organization].delete :nodes
end
end
它将在参数中设置正确的属性并且仍然使用所有 accepts_nested_attributes 功能。
我正在尝试编写一个处理 JSON 的更新方法。 JSON 看起来像这样:
{
"organization": {
"id": 1,
"nodes": [
{
"id": 1,
"title": "Hello",
"description": "My description."
},
{
"id": 101,
"title": "fdhgh",
"description": "My description."
}
]
}
}
组织模型:
has_many :nodes
accepts_nested_attributes_for :nodes, reject_if: :new_record?
组织序列化程序:
attributes :id
has_many :nodes
节点序列化器:
attributes :id, :title, :description
组织控制器中的更新方法:
def update
organization = Organization.find(params[:id])
if organization.update_attributes(nodes_attributes: node_params.except(:id))
render json: organization, status: :ok
else
render json: organization, status: :failed
end
end
private
def node_params
params.require(:organization).permit(nodes: [:id, :title, :description])
end
我还尝试将 accepts_nested_attributes_for
添加到组织 serializer,但这似乎不正确,因为它产生了错误 (undefined method 'accepts_nested_attributes_for'
),所以我只将 accepts_nested_attributes_for
添加到模型而不是序列化程序。
上面的代码生成下面的错误,参考更新方法中的 update_attributes
行。我做错了什么?
no implicit conversion of String into Integer
在调试器中 node_params
returns:
Unpermitted parameters: id
{"nodes"=>[{"id"=>101, "title"=>"gsdgdsfgsdg.", "description"=>"dgdsfgd."}, {"id"=>1, "title"=>"ertret.", "description"=>"etewtete."}]}
更新: 使用以下命令使其工作:
def update
organization = Organization.find(params[:id])
if organization.update_attributes(nodes_params)
render json: organization, status: :ok
else
render json: organization, status: :failed
end
end
private
def node_params
params.require(:organization).permit(:id, nodes_attributes: [:id, :title, :description])
end
我向序列化程序添加了 root: :nodes_attributes
。
现在一切正常,但是 我担心在 node_params
中包含 ID。这样安全吗? 现在难道不能编辑 organization
和 node
的 ID(这是不允许的)吗? 以下是否是不允许它更新 id 的正确解决方案:
if organization.update_attributes(nodes_params.except(:id, nodes_attributes: [:id]))
看起来超级接近。
您的 json 子对象 'nodes' 需要 'nodes_attributes'。
{
"organization": {
"id": 1,
"nodes_attributes": [
{
"id": 1,
"title": "Hello",
"description": "My description."
},
{
"id": 101,
"title": "fdhgh",
"description": "My description."
}
]
}
}
你可以做这种事。将其放入您的控制器中。
before_action do
if params[:organization]
params[:organization][:nodes_attributes] ||= params[:organization].delete :nodes
end
end
它将在参数中设置正确的属性并且仍然使用所有 accepts_nested_attributes 功能。