Rails:如何通过关联RESTful查询模型?

时间:2009-08-11 01:18:34

标签: ruby-on-rails rest

我没有使用Ruby on Rails获得REST,我希望有人可以帮助我。

想象一下,我正在构建一个跟踪窗口小部件和拥有这些窗口小部件的用户的网站。所以我有一个UsersController和一个WidgetsController,我可以通过索引操作得到一个Widgets或Users列表:

GET /users
GET /widgets

我可以通过show actions获取特定的用户或小部件:

GET /users/id
GET /widgets/id

我明白了。

我感到困惑的是,我将使用哪些RESTful请求来检索属于特定用户的小部件列表?这是一个发送到UsersController或WidgetsController的请求吗?它使用了7种RESTful操作中的哪一种?

我是否会创建自定义操作?我认为自定义操作很少见,但这似乎是一个非常常见的用例。

谢谢!

3 个答案:

答案 0 :(得分:4)

属于用户foo的小部件列表的网址如下所示:

/users/foo/widgets

然后,您可以选择如何为每个小部件执行网址。这是可能的:

/users/foo/widgets/bar

但我更喜欢这个:

/widgets/bar

您的路线如下所示:

map.resources :users, :has_many => :widgets, :shallow => true
map.resources :widgets, :has_many => :users, :shallow => true

(这是来自记忆,我可能搞砸了一个或多个细节)

处理/user/foo/widgets的控制器方法是index的{​​{1}}操作。它测试WidgetController参数是否存在,并根据该参数限制返回的小部件。 (或检索user_id用户并将foo设置为@widgets。)

更新:对Rails Guides中回答原始问题的嵌套路由有一个很好的概述。

更新2 哦,是的,我的意思是链接到某些documentation

答案 1 :(得分:1)

您发现设计过程很困难,因为您在设计内容文档时尝试根据网址空间设计网站。

以下是满足您要求的骨架媒体类型。

媒体类型:application / vnd.yourcompany.collections + xml

<Collections>
  <Widgets href="http://yoursite.com/{9BCCD309-644C-4fb8-A35E-A8B5E6AC4AE8}"/>
  <Users href="http://yoursite.com/{BE57DC2D-8FE7-45e3-9362-AF5F607D62B6}"/>
</Collections>

媒体类型:application / vnd.yourcompany.Widgets + xml

<Widgets>
  <Widget href="http://yoursite.com/{4A7B5583-5D09-4cf3-9781-1084977769C0}"/>
  <Widget href="http://yoursite.com/{0D6A72E8-6088-462c-A97A-70BC43E25475}"/>
</Widgets>

媒体类型:application / vnd.yourcompany.Users + xml

<Users>
  <User href="http://yoursite.com/{6321D95E-7EDB-46b8-9430-AB57EA067B06}"/>
  <User href="http://yoursite.com/{0D6A72E8-6088-462c-A97A-70BC43E25475}"/>
</Users>

媒体类型:application / vnd.yourcompany.Widget + xml

<Widget>
  <Property1>99</Property1>
  <Property2>A Description</Property2>
  <UsersOfWidget href="http://yoursite.com/{26995C10-CA1D-4f1f-9065-2246A8426DA7}"/>
</Widget>

媒体类型:application / vnd.yourcompany.User + xml

<User>
  <Name>Joe Smith</User> 
  <WidgetsOwnedByUser href="http://yoursite.com/{D718A2E6-6ADD-4d6e-A1E7-6DA68EDE0BD3}"/>
</User>

显然,这套媒体类型只是解决问题的众多潜在解决方案之一。我想引起你注意的问题是,URL在很大程度上是无关紧要的。文件如何相互关联很重要。当您以这种方式查看时,不难区分用户使用的窗口小部件和使用窗口小部件的用户。

现在,如何将其映射到一组Rails控制器是另一回事。问题不在于设计RESTful解决方案很困难,只是Rails似乎没有很自然地映射。并不是说我对Rails有很多经验,所以请考虑一下它的价值。我相信你应该为每个资源配备一个控制器,并且Rails试图将资源列表和资源本身压缩到单个控制器这一事实是错误的。在我看来,客户和客户是两种不同的资源。

修改:可能链接这些资源的可能的网址集。

/Widgets
/Users
/Widget/1
/User/99
/Widget/1/UsersOfWidget
/User/99/WidgetsOwned

我会为每个端点创建一个控制器。

答案 2 :(得分:1)

我认为Darrel正试图教你一般的REST,因为他说过于担心URL设计可能表明你并没有真正设计REST。例如,正如Darrel所示,您的用户表示可以携带指向他/她拥有的小部件的链接(或链接到用于搜索用户自己的小部件的URL)。