Comment puis-je passer JSON à une application RAILS il sera créé des objets enfants imbriqués dans une relation has_many?création d'objets nichés JSON dans Rails
Voici ce que j'ai jusqu'à présent:
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 Commute, j'ai configuré un contrôleur standard. J'aimerais pouvoir créer un objet Commute ainsi que plusieurs objets Emplacement enfant dans un seul appel REST à l'aide de JSON. J'ai essayé des choses comme ça:
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 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 j'exécute, je reçois cette sortie:
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 semble Tout comme les emplacements, le tableau JSON est en cours de lecture mais n'est pas interprété comme un objet Location.
Je peux facilement changer le client ou le serveur, la solution pourrait venir de chaque côté.
Alors, est-RAILS rendre cela facile pour moi de le faire? Ou ai-je besoin d'ajouter un support pour cela à mon objet Commute? Peut-être ajouter une méthode from_json?
Merci pour toute aide.
Comme j'ai travaillé à travers cela, une solution qui fonctionne est de modifier mon contrôleur. Mais cela ne semble pas être la façon de le faire, alors s'il vous plaît laissez-moi savoir s'il y a un meilleur moyen.
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
Vous semblez être en mesure de contrôler le JSON source, mais si vous ne pouviez pas, comment géreriez-vous les "emplacements"? – Jerome
Jetez un oeil, je viens de poster une modification d'une réponse qui a été supprimée. –
Pour toute personne ayant encore des problèmes avec cela, vous devez autoriser manuellement les attributs de votre contrôleur. Exemple: 'params.require (: commute) .permit (: minutes,: startTime, locations_attributes: [: latitude,: longitude])' – Kevin