gpt4 book ai didi

ruby-on-rails - 如何将 REST 与以 XML 表示的嵌套资源一起使用?

转载 作者:数据小太阳 更新时间:2023-10-29 01:55:14 26 4
gpt4 key购买 nike

我的目标是通过一个 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

在文件 ./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

...现在我们将在树 Controller 的(生成的)“创建”方法中得到一个服务器错误: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 语法?或者我是否必须手动修改树的 Controller ,因为生成的 Controller 没有涵盖这种情况?

最佳答案

实现此目的的一种方法是覆盖树模型上的 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

这是首选。

关于ruby-on-rails - 如何将 REST 与以 XML 表示的嵌套资源一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/556262/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com