Il mio obiettivo è creare risorse nidificate tramite una richiesta REST. Le richieste REST sono rappresentate tramite un documento XML. Funziona bene per le singole risorse, ma non sono riuscito a gestirle per quelle nidificate. OK ti darò un piccolo esempio dopo.Come utilizzare REST con risorse nidificate rappresentate in XML?
anzitutto creare un nuovo rotaie proiettano
rails forrest
Poi si generano i ponteggi di due risorse, gli alberi e nidi degli uccelli.
./script/generate scaffold tree name:string
./script/generate scaffold bird_nest tree_id:integer bird_type:string eggs_count:integer
Nel File ./forrest/app/models/tree.rb inseriamo la linea "has_many" di seguito a causa di un albero può avere nidi di molti uccelli :-)
class Tree < ActiveRecord::Base
has_many :bird_nests
end
Nel File ./forrest/app/models/bird_nest.rb inseriamo la riga "belongs_to" qui sotto perché ogni nido d'uccello dovrebbe appartenere ad un albero.
class BirdNest < ActiveRecord::Base
belongs_to :tree
end
Successivamente abbiamo impostare il database e avviare il server:
rake db:create
rake db:migrate
./script/server
Basta copiare e incollare questo sniplet XML in un file denominato "tree.xml" ...
<tree>
<name>Apple</name>
</tree>
... e postalo al servizio da cURL per creare un nuovo albero:
curl -H 'Content-type: application/xml' -H 'Accept: application/xml' -d @tree.xml http://localhost:3000/trees/ -X POST
Funziona bene. Anche per il nido d'uccello XML (nome del file "bird-nest.xml") separatamente. Se inviamo questo ...
<bird-nest>
<tree-id>1</tree-id>
<bird-type>Sparrow</bird-type>
<eggs-count>2</eggs-count>
</bird-nest>
... anche tramite la seguente istruzione cURL. Quella risorsa è stata creata correttamente!
curl -H 'Content-type: application/xml' -H 'Accept: application/xml' -d @bird-nest.xml http://localhost:3000/bird_nests/ -X POST
OK tutto va bene finora. Ora arriva il punto in cui la gomma incontra la strada. Creiamo entrambe le risorse in un'unica richiesta. Così qui è l'XML per il nostro albero che contiene il nido d'uccello uno:
<tree>
<name>Cherry</name>
<bird-nests>
<bird-nest>
<bird-type>Blackbird</bird-type>
<eggs-count>2</eggs-count>
</bird-nest>
</bird-nests>
</tree>
Abbiamo innescare la richiesta appropriato utilizzando di nuovo curl ...
curl -H 'Content-type: application/xml' -H 'Accept: application/xml' -d @tree-and-bird_nest.xml http://localhost:3000/trees/ -X POST
... e adesso ci prendiamo un errore del server nel (generato) "creare" il metodo del controllore della albero: AssociationTypeMismatch (birdnest previsto, Array ottenuto)
nel mio punto di vista questa è la parte importante del log del server per quanto riguarda gli attributi ricevuti e messa errore ge:
Processing TreesController#create (for 127.0.0.1 at 2009-02-17 11:29:20) [POST]
Session ID: 8373b8df7629332d4e251a18e844c7f9
Parameters: {"action"=>"create", "controller"=>"trees", "tree"=>{"name"=>"Cherry", "bird_nests"=>{"bird_nest"=>{"bird_type"=>"Blackbird", "eggs_count"=>"2"}}}}
SQL (0.000082) SET NAMES 'utf8'
SQL (0.000051) SET SQL_AUTO_IS_NULL=0
Tree Columns (0.000544) SHOW FIELDS FROM `trees`
ActiveRecord::AssociationTypeMismatch (BirdNest expected, got Array):
/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:150:in `raise_on_type_mismatch'
/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb:146:in `replace'
/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb:146:in `each'
/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb:146:in `replace'
/vendor/rails/activerecord/lib/active_record/associations.rb:1048:in `bird_nests='
/vendor/rails/activerecord/lib/active_record/base.rb:2117:in `send'
/vendor/rails/activerecord/lib/active_record/base.rb:2117:in `attributes='
/vendor/rails/activerecord/lib/active_record/base.rb:2116:in `each'
/vendor/rails/activerecord/lib/active_record/base.rb:2116:in `attributes='
/vendor/rails/activerecord/lib/active_record/base.rb:1926:in `initialize'
/app/controllers/trees_controller.rb:43:in `new'
/app/controllers/trees_controller.rb:43:in `create'
Quindi la mia domanda è cosa sto facendo male per quanto riguarda l'annidamento delle risorse XML. Quale sarebbe la sintassi XML corretta? O devo modificare manualmente il controller dell'albero in quanto questo non è coperto da quello generato?
Sembra che potrebbe essere necessario modificare TreesController per creare un'azione per gestire la creazione di oggetti BirdsNest. Puoi pubblicare una copia di TreesController per creare un'azione? – hernan43
L'azione di creazione è l'azione predefinita che è stata generata nei passaggi precedenti (vedere "generare scaffold"). –