Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
277 views
in Technique[技术] by (71.8m points)

Rails not recognizing nested JSON objects in POST request

Basically, I have two models - Company and Location.

class Company < ActiveRecord::Base
  has_many :locations, dependent: :destroy
  accepts_nested_attributes_for :locations # Not sure if needed.
end

class Location < ActiveRecord::Base
  belongs_to :company
end

When creating a Company (i.e. a POST to /companies), I want to be able to create its Locations in the same request. But for some reason, I cannot get Rails to recognize the array of Locations nested inside the Company. It seems to rip the nested JSON array out and place it into the "root" of the JSON request.

Example POST request using cURL:

curl -X POST -H "Accept: Application/json" -H "Content-Type: application/json" http://example.com/companies -d '{"employee_count":320,"locations":[{"lat":"-47.5", "lon":"120.3"},{"lat":"78.27", "lon":"101.09"}]}'

Example server output:

Started POST "/companies"
Processing by CompaniesController#create as Application/json
Parameters: {"employee_count"=>320, "locations"=>[{"lat"=>"-47.5", "lon"=>"120.3"}, {"lat"=>"78.27", "lon"=>"101.09"}], "company"=>{"employee_count"=>320}}

As you can see, the locations array is no longer inside the company object, so when CompaniesController#create attempts create the Company instance, it's array of Locations is nil. Also, the employee_count attribute is repeated twice, which is kind of strange too. Does anyone know why is this happening and how to fix it?

For reference, this is what the whitelist in my CompaniesController looks like:

params.require(:company).permit(
  :employee_count,
  locations: [:lat, :lon]
)

My server is Thin (1.6.2), and it's pretty much an entirely new/default Rails app with no special configurations.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Okay, looks like I needed to rename locations to locations_updates in my POST request (thanks to the users in the comments who suggested this).

I also needed to encapsulate all attributes in an "outer" company object, instead of being at the "root" of the JSON. Example:

curl -X POST -H "Accept: Application/json" -H "Content-Type: application/json" http://example.com/companies -d '{"company":{"employee_count":320,"locations":[{"lat":"-47.5", "lon":"120.3"},{"lat":"78.27", "lon":"101.09"}]}}'

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...