加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 如何将REST用于以XML表示的嵌套资源?

发布时间:2020-12-17 03:33:27 所属栏目:百科 来源:网络整理
导读:我的目标是通过一个REST请求创建嵌套资源. REST请求通过 XML文档表示.这适用于单个资源,但我无法管理嵌套的资源.好的我接下来会给你一个小例子. 首先创建一个新的rails项目 rails forrest 接下来,我们生成两种资源的支架,树木和鸟巢. ./script/generate scaf
我的目标是通过一个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

这是首选方案.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读