如何将JSON传递给RAILS应用程序,以便它在一个has_many关系中创建嵌套的子对象?
Here's what I have so far:
两个模型对象.
class Commute < ActiveRecord::Base
has_many :locations
accepts_nested_attributes_for :locations, :allow_destroy => true
end
class Location < ActiveRecord::Base
belongs_to :commute
end
对于通勤,我设置了一个标准控制器.我希望能够使用JSON在一个REST调用中创建一个通勤对象以及几个子位置对象.我一直在try 这样的事情:
curl -H "Content-Type:application/json" -H "Accept:application/json"
-d "{\"commute\":{\"minutes\":0,
\"startTime\":\"Wed May 06 22:14:12 EDT 2009\",
\"locations\":[{\"latitude\":\"40.4220061\",
\"longitude\":\"40.4220061\"}]}}" http://localhost:3000/commutes
或者更具可读性,JSON是:
{
"commute": {
"minutes": 0,
"startTime": "Wed May 06 22:14:12 EDT 2009",
"locations": [
{
"latitude": "40.4220061",
"longitude": "40.4220061"
}
]
}
}
When I execute that, I get this output:
Processing CommutesController#create (for 127.0.0.1 at 2009-05-10 09:48:04) [POST]
Parameters: {"commute"=>{"minutes"=>0, "locations"=>[{"latitude"=>"40.4220061", "longitude"=>"40.4220061"}], "startTime"=>"Wed May 06 22:14:12 EDT 2009"}}
ActiveRecord::AssociationTypeMismatch (Location(#19300550) expected, got HashWithIndifferentAccess(#2654720)):
app/controllers/commutes_controller.rb:46:in `new'
app/controllers/commutes_controller.rb:46:in `create'
看起来像是读取了locations JSON数组,但没有被解释为Location对象.
我可以很容易地更改客户端或服务器,因此解决方案可以来自任何一方.
So, does RAILS make this easy for me to do? Or do I need to add in some support for this to my Commute object? Perhaps add a from_json method?
Thanks for any help.
As I've been working through this, one solution that works is to modify my controller. But this doesn't seem the "rails" way of doing it, so please still let me know if there's a better way.
def create
locations = params[:commute].delete("locations");
@commute = Commute.new(params[:commute])
result = @commute.save
if locations
locations.each do |location|
@commute.locations.create(location)
end
end
respond_to do |format|
if result
flash[:notice] = 'Commute was successfully created.'
format.html { redirect_to(@commute) }
format.xml { render :xml => @commute, :status => :created, :location => @commute }
else
format.html { render :action => "new" }
format.xml { render :xml => @commute.errors, :status => :unprocessable_entity }
end
end
end