Mi objetivo es crear recursos anidados a través de una solicitud REST. Las solicitudes REST se representan a través de un documento XML. Eso funciona bien para los recursos individuales, pero no pude gestionarlo para los anidados. OK, les daré un pequeño ejemplo a continuación.¿Cómo usar REST con recursos anidados que están representados en XML?
En primer lugar crear un nuevo rieles proyectan
rails forrest
A continuación se generan los andamios de dos recursos, los árboles y los nidos de las aves.
./script/generate scaffold tree name:string
./script/generate scaffold bird_nest tree_id:integer bird_type:string eggs_count:integer
en el archivo ./forrest/app/models/tree.rb insertamos la línea "has_many" a continuación debido a que un árbol puede tener muchos nidos de aves :-)
class Tree < ActiveRecord::Base
has_many :bird_nests
end
en el archivo ./forrest/app/models/bird_nest.rb insertamos la línea "belongs_to" a continuación porque cada nido de pájaro debe pertenecer a un árbol.
class BirdNest < ActiveRecord::Base
belongs_to :tree
end
Posteriormente hemos creado la base de datos e iniciar el servidor:
rake db:create
rake db:migrate
./script/server
Simplemente copia y pega este sniplet XML en un archivo denominado "tree.xml" ...
<tree>
<name>Apple</name>
</tree>
... y publicarlo en el servicio por cURL para crear un nuevo árbol:
curl -H 'Content-type: application/xml' -H 'Accept: application/xml' -d @tree.xml http://localhost:3000/trees/ -X POST
Esto funciona bien. También para el nido de pájaro XML (nombre de archivo "bird-nest.xml") por separado. Si enviamos esto ...
<bird-nest>
<tree-id>1</tree-id>
<bird-type>Sparrow</bird-type>
<eggs-count>2</eggs-count>
</bird-nest>
... también a través de la siguiente instrucción cURL. ¡Ese recurso se crea correctamente!
curl -H 'Content-type: application/xml' -H 'Accept: application/xml' -d @bird-nest.xml http://localhost:3000/bird_nests/ -X POST
OK everything está bien hasta el momento. Ahora viene el punto donde la goma se encuentra con la carretera. Creamos ambos recursos en una sola solicitud. Así que aquí es el XML para nuestro árbol que contiene el nido de un ave:
<tree>
<name>Cherry</name>
<bird-nests>
<bird-nest>
<bird-type>Blackbird</bird-type>
<eggs-count>2</eggs-count>
</bird-nest>
</bird-nests>
</tree>
Nos activan la solicitud correspondiente mediante el uso de rizo de nuevo ...
curl -H 'Content-type: application/xml' -H 'Accept: application/xml' -d @tree-and-bird_nest.xml http://localhost:3000/trees/ -X POST
... y ahora vamos a tener una error de servidor en la (generado) "crear" método del controlador del árbol: AssociationTypeMismatch (birdnest espera, array GOT)
en mi punto de vista esta es la parte importante de registro del servidor con respecto a los atributos recibidos y messa de error 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'
Así que mi pregunta es qué estoy haciendo mal con respecto a la anidación de los recursos XML. ¿Cuál sería la sintaxis correcta de XML? ¿O tengo que modificar el controlador del árbol manualmente ya que este caso no está cubierto por el generado?
Parece que es posible que necesite editar la acción Crear de TreesController para gestionar la creación de objetos BirdsNest. ¿Puedes publicar una copia de TreesController create action? – hernan43
La acción de creación es la acción predeterminada que se generó en los pasos anteriores (consulte "generar andamio"). –