私の目的は、1 つの REST リクエストでネストされたリソースを作成することです。REST 要求は、XML ドキュメントを介して表されます。単一のリソースでは問題なく機能しますが、ネストされたリソースでは管理できませんでした。OK、次に少し例を挙げます。
最初に新しい Rails プロジェクトを作成します
rails forrest
次に、木と鳥の巣という 2 つのリソースの足場を生成します。
./script/generate scaffold tree name:string
./script/generate scaffold bird_nest tree_id:integer bird_type:string eggs_count:integer
ファイル ./forrest/app/models/tree.rb で、以下に「has_many」行を挿入します。これは、木には多くの鳥の巣がある可能性があるためです :-)
class Tree < ActiveRecord::Base
has_many :bird_nests
end
ファイル ./forrest/app/models/bird_nest.rb で、以下に「belongs_to」行を挿入します。これは、すべての鳥の巣がツリーに属する必要があるためです。
class BirdNest < ActiveRecord::Base
belongs_to :tree
end
その後、データベースをセットアップしてサーバーを起動します。
rake db:create
rake db:migrate
./script/server
この XML スニペットを「tree.xml」という名前のファイルにコピー アンド ペーストするだけです...
<tree>
<name>Apple</name>
</tree>
...それを cURL でサービスに投稿して、新しいツリーを作成します。
curl -H 'Content-type: application/xml' -H 'Accept: application/xml' -d @tree.xml http://localhost:3000/trees/ -X POST
これはうまくいきます。ツバメの巣用XML(ファイル名「bird-nest.xml」)も別途。これを送ったら…
<bird-nest>
<tree-id>1</tree-id>
<bird-type>Sparrow</bird-type>
<eggs-count>2</eggs-count>
</bird-nest>
...また、次の cURL ステートメントを介して。そのリソースは適切に作成されています。
curl -H 'Content-type: application/xml' -H 'Accept: application/xml' -d @bird-nest.xml http://localhost:3000/bird_nests/ -X POST
OK、これまでのところすべて問題ありません。ゴムが道路と出会うポイントが来ます。1 つのリクエストで両方のリソースを作成します。1 つの鳥の巣を含むツリーの XML は次のとおりです。
<tree>
<name>Cherry</name>
<bird-nests>
<bird-nest>
<bird-type>Blackbird</bird-type>
<eggs-count>2</eggs-count>
</bird-nest>
</bird-nests>
</tree>
再度 cURL を使用して、適切なリクエストをトリガーします...
curl -H 'Content-type: application/xml' -H 'Accept: application/xml' -d @tree-and-bird_nest.xml http://localhost:3000/trees/ -X POST
...そして、ツリーのコントローラーの (生成された) "create" メソッドでサーバー エラーが発生します: AssociationTypeMismatch (BirdNest expected, got Array)
私の見解では、これは受信した属性とエラー メッセージに関するサーバーのログの重要な部分です。
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'
だから私の質問は、XML リソースのネストに関して私が間違っていることです。正しい XML 構文はどれですか? または、このケースは生成されたものでカバーされていないため、ツリーのコントローラーを手動で変更する必要がありますか?