Comment puis-je passer JSON à une application RAILS, de sorte qu'il sera créé imbriquée à l'enfant des objets dans un has_many relation?
Voici ce que j'ai à ce jour:
Deux objets de modèle.
class Commute < ActiveRecord::Base
has_many :locations
accepts_nested_attributes_for :locations, :allow_destroy => true
end
class Location < ActiveRecord::Base
belongs_to :commute
end
Avec la navette, j'ai un contrôleur standard mis en place. Je voudrais être en mesure de créer un Commute objet ainsi que plusieurs enfants de l'Emplacement des objets dans une seule RESTE l'appel à l'aide de JSON. J'ai essayé des choses comme ceci:
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
Ou des plus lisible, le JSON est:
{
"commute": {
"minutes": 0,
"startTime": "Wed May 06 22:14:12 EDT 2009",
"locations": [
{
"latitude": "40.4220061",
"longitude": "40.4220061"
}
]
}
}
Quand je l'exécuter, j'obtiens ce résultat:
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'
Il ressemble à l'emplacement tableau JSON est de le lire, mais pas interprétée comme un objet d'Emplacement.
Je peux facilement changer soit le client ou le serveur, de sorte que la solution pourrait venir de chaque côté.
Donc, ne RAILS de rendre cela facile à faire pour moi? Ou dois-je besoin d'ajouter dans certains de support pour cette pour mon trajet de l'objet? Peut-être ajouter un from_json méthode?
Merci pour toute aide.
Comme je l'ai déjà travaillé dans ce, une solution qui fonctionne est de modifier mon contrôleur. Mais cela ne semble pas les "rails" manière de faire, alors vous pouvez toujours vous laissez-moi savoir si il ya une meilleure façon.
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