ruby-on-rails – 如何将REST用于以XML表示的嵌套资源?
我的目标是通过一个REST请求创建嵌套资源. REST请求通过
XML文档表示.这适用于单个资源,但我无法管理嵌套的资源.好的我接下来会给你一个小例子.
首先创建一个新的rails项目 rails forrest 接下来,我们生成两种资源的支架,树木和鸟巢. ./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 在File ./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 好的到目前为止一切都很好.现在,橡胶遇到了道路.我们在一个请求中创建两个资源.所以这里是我们树的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语法?或者我是否必须手动修改树的控制器,因为生成的情况不包括这种情况? 解决方法
实现此目的的一种方法是覆盖树模型上的bird_nests =方法.
def bird_nests=(attrs_array) attrs_array.each do |attrs| bird_nests.build(attrs) end end 这里唯一的问题是你丢失了setter的默认行为,这可能是也可能不是你应用中的问题. 如果您正在运行更新版本的Rails,您可以按照此处所述启用质量分配: http://github.com/rails/rails/commit/e0750d6a5c7f621e4ca12205137c0b135cab444a 和这里: http://ryandaigle.com/articles/2008/7/19/what-s-new-in-edge-rails-nested-models class Tree < ActiveRecord::Base has_many :bird_nests,:accessible => true end 这是首选方案. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |