Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to use REST with nested resources which are represented in XML?
    text
    copied!<p>My aim is to create nested resources via one REST request. The REST requests is represented via a XML document. That works fine for single resources but I could not manage it for nested ones. OK I'll give you a little example next.</p> <p>First create a new rails project</p> <pre><code>rails forrest </code></pre> <p>Next we generate the scaffolds of two resources, the trees and the bird's nests.</p> <pre><code>./script/generate scaffold tree name:string ./script/generate scaffold bird_nest tree_id:integer bird_type:string eggs_count:integer </code></pre> <p>In the File ./forrest/app/models/tree.rb we insert the "has_many" line below because a tree can have many bird's nests :-)</p> <pre><code>class Tree &lt; ActiveRecord::Base has_many :bird_nests end </code></pre> <p>In the File ./forrest/app/models/bird_nest.rb we insert the "belongs_to" line below because every bird's nest should belong to a tree.</p> <pre><code>class BirdNest &lt; ActiveRecord::Base belongs_to :tree end </code></pre> <p>Afterwards we set up the database and start the server:</p> <pre><code>rake db:create rake db:migrate ./script/server </code></pre> <p>Just copy and paste this XML sniplet to a file named "tree.xml"...</p> <pre><code>&lt;tree&gt; &lt;name&gt;Apple&lt;/name&gt; &lt;/tree&gt; </code></pre> <p>...and post it to the service by cURL to create a new tree:</p> <pre><code>curl -H 'Content-type: application/xml' -H 'Accept: application/xml' -d @tree.xml http://localhost:3000/trees/ -X POST </code></pre> <p>This works fine. Also for the bird's nest XML (file name "bird-nest.xml") separately. If we send this...</p> <pre><code>&lt;bird-nest&gt; &lt;tree-id&gt;1&lt;/tree-id&gt; &lt;bird-type&gt;Sparrow&lt;/bird-type&gt; &lt;eggs-count&gt;2&lt;/eggs-count&gt; &lt;/bird-nest&gt; </code></pre> <p>...also via the following cURL statement. That resource is created properly!</p> <pre><code>curl -H 'Content-type: application/xml' -H 'Accept: application/xml' -d @bird-nest.xml http://localhost:3000/bird_nests/ -X POST </code></pre> <p>OK everything is fine so far. Now comes the point where the rubber meets the road. We create both resources in one request. So here is the XML for our tree which contains one bird's nest:</p> <pre><code>&lt;tree&gt; &lt;name&gt;Cherry&lt;/name&gt; &lt;bird-nests&gt; &lt;bird-nest&gt; &lt;bird-type&gt;Blackbird&lt;/bird-type&gt; &lt;eggs-count&gt;2&lt;/eggs-count&gt; &lt;/bird-nest&gt; &lt;/bird-nests&gt; &lt;/tree&gt; </code></pre> <p>We trigger the appropriate request by using cURL again...</p> <pre><code>curl -H 'Content-type: application/xml' -H 'Accept: application/xml' -d @tree-and-bird_nest.xml http://localhost:3000/trees/ -X POST </code></pre> <p>...and now we'll get a server error in the (generated) "create" method of the tree's controller: <strong>AssociationTypeMismatch (BirdNest expected, got Array)</strong> </p> <p>In my point of view this is the important part of the server's log regarding received attributes and error message:</p> <pre><code>Processing TreesController#create (for 127.0.0.1 at 2009-02-17 11:29:20) [POST] Session ID: 8373b8df7629332d4e251a18e844c7f9 Parameters: {"action"=&gt;"create", "controller"=&gt;"trees", "tree"=&gt;{"name"=&gt;"Cherry", "bird_nests"=&gt;{"bird_nest"=&gt;{"bird_type"=&gt;"Blackbird", "eggs_count"=&gt;"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' </code></pre> <p>So my question is what I'm doing wrong regarding the nesting of the XML resources. Which would be the right XML syntax? Or do I have to modify the tree's controller manually as this case is not covered by the generated one?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload