How to use nested_attributes when processing JSON?

╄→尐↘猪︶ㄣ 提交于 2020-01-17 12:41:56

问题


I'm trying to write an update method that processes JSON. The JSON looks like this:

{
  "organization": {
    "id": 1,
    "nodes": [
      {
        "id": 1,
        "title": "Hello",
        "description": "My description."
      },
      {
        "id": 101,
        "title": "fdhgh",
        "description": "My description."
      }
    ]
  }
}

Organization model:

has_many :nodes
accepts_nested_attributes_for :nodes, reject_if: :new_record?

Organization serializer:

attributes :id
has_many :nodes

Node serializer:

attributes :id, :title, :description

Update method in the organizations controller:

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

I also tried adding accepts_nested_attributes_for to the organization serializer, but that does not seem to be correct as it generated an error (undefined method 'accepts_nested_attributes_for'), so I've only added accepts_nested_attributes_for to the model and not to the serializer.

The code above generates the error below, referring to the update_attributes line in the update method. What am I doing wrong?

no implicit conversion of String into Integer

In debugger node_params returns:

Unpermitted parameters: id
{"nodes"=>[{"id"=>101, "title"=>"gsdgdsfgsdg.", "description"=>"dgdsfgd."}, {"id"=>1, "title"=>"ertret.", "description"=>"etewtete."}]}

Update: Got it to work using the following:

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

To the serializer I added root: :nodes_attributes.

It now all works, but I'm concerned about including the id in node_params. Is that safe? Wouldn't it now be possible to edit the id of the organization and node (which shouldn't be allowed)? Would the following be a proper solution to not allowing it to update the id's:

if organization.update_attributes(nodes_params.except(:id, nodes_attributes: [:id]))

回答1:


looks super close.

Your json child object 'nodes' need to be 'nodes_attributes'.

{
  "organization": {
    "id": 1,
    "nodes_attributes": [
      {
        "id": 1,
        "title": "Hello",
        "description": "My description."
      },
      {
        "id": 101,
        "title": "fdhgh",
        "description": "My description."
      }
    ]
  }
}



回答2:


You can do this sort of thing. Put this in your controller.

before_action do
  if params[:organization]
    params[:organization][:nodes_attributes] ||= params[:organization].delete :nodes
  end
end

It will set the correct attribute in params and still use all the accepts_nested_attributes features.



来源:https://stackoverflow.com/questions/34828645/how-to-use-nested-attributes-when-processing-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!