REST on Rails指南4:路由 - oyaji's Blog

REST on Rails指南4:路由

oyaji posted @ 2010年12月20日 05:57 in rails with tags rails REST , 1813 阅读

通过上一讲我们了解到,RESTful设计的关键就是定义系统中的资源,这一讲我们将学习在Rails中,如何将请求路由到我们的资源,以及我们应该如何来处理它。

不过,有一点需要先说明:REST并不是Rails的一部分,在Rails出现之前,REST的概念已经存在很多年了,并且REST的应用也并不局限于Web,事实上,它也可以应用到其它各种应用软件的开发中。

资源就是控制器

在我们正式开始之前,我们需要首先明确,在Rails中,资源和model并不总是一对一的关系,有时资源仅仅只是你应用逻辑中的一个实体的抽象,并不需要 映射到你的数据库。但资源跟控制器总是一对一的,也就是每个资源都必须有一个与它相对应的控制器,并且你需要重新理解控制器,现在控制器只是REST接口 的具体实现,它的全部作用就是根据客户的请求返回资源的某种表示(HTML,XML等)。

所以,就像第2章讲的,我们不在需要去设计那无穷尽的API了,现在我们的控制器只需要定义7个方法:

  • show,处理针对单个资源的GET请求
  • create,处理POST请求,并将创建一个新资源
  • update,处理PUT请求,并更新指定的资源
  • destroy,处理DELETE请求,销毁一个资源
  • index,处理针对多个资源的GET请求
  • new,GET请求,返回一个用于创建资源的表单,
  • edit,GET请求,返回一个用于更新资源的表单

Rails 会帮助我们将用户的请求路由到某个合适的方法,当然,你并不需要实现这全部的7个方法,如果你的系统不允许用户创建和修改资源,那么你只需要实现 index和show方法就可以了。

不过更有可能的一种情况是你觉得这7个方法根本不够,你当然可以选择向控制器添加新的方法,但这其实是因为你的设计遗漏了一些资源,因为我建议,在你向控制器添加新方法之前,最好先重新考虑下你的设计。

方法已经定义好了,下一步的任务就是将用户的请求路由到指定的方法,在router.rb中,你可能会看到这样的路由:

map.connect '/airports/:action/:id', :controller = 'airports'

这条语句将映射/airports/open/45到airports控制器的open方法,你可以通过params[:id]获取URL中的参数45。但是REST路由有些特殊,它需要同时考虑URL和请求的类型,因此同样是发往/airports/1的请求,如果是GET请求,它需要被路由到airports的show方法,而DELETE请求则需要被路由到DELETE方法。

不过幸运的是,从Rails1.2开始,我们不再需要通过map.connect来手动的配置REST路由,map.resources会帮我们搞定一切:

map.resources 'airports'

这句话将创建如下的路由规则:

  • 针对/airports/ 的POST请求将被路由到create方法
  • 针对/airports/1 的GET请求将被路由到show方法
  • 针对/airports/1的PUT请求被路由到update方法
  • 针对/airports/1 的DELETE请求被路由到destroy方法
  • 针对/airports/ 的GET请求被路由到index方法
  • 针对/airports/new 的GET请求被路由到new方法
  • 针对/airports/1;edit 的GET请求被路由到edit方法

注意:最后一条逗号分隔的URL看起来很丑陋,但它们在Rails1.2.3中是合法的,不过不用苦恼,它们将在Rails2.0中被去除

现在我们已经完成了URL的路由,下面我们需要做的就是实现这些方法:
不过先别着急着码代码,从Rails1.2开始,我们有了一个新的生成器(generator):scaffold_resource,使用它我们可以很轻松的生成一个符合REST规范的Rails框架,它包含:

  • 资源所对应的model
  • 资源的migration文件
  • 资源所对应的控制器,控制器已经包含了REST所需的7个方法的实现
  • 这7个方法所对应的RHTML文件
  • 一条映射用户请求的路由

让我们仍然从第三讲的例子开始,首先创建一个新程序,然后为它添加一个airport资源:

D:\study>rails REST
D:\study>cd REST
D:\study\REST>ruby script/generate scaffold_resource airport name:string designator:string

修改database.yml文件,设置好你的数据库链接,然后执行:

D:\study\REST>rake db:migrate
D:\study\REST>ruby script/server

现在定位你的浏览器到http://localhost:3000/airports/new,你应该已经可以创建一个新机场了,是不是很神奇?现在,让我们来看看airports_controller.rb,所有的东西都在那了。

你应该会在控制器代码中看到一些奇怪的respond_to块,这正是我们整个REST实现的关键所在,我们将在下一讲详细探讨respond_to的细节。

Avatar_small
oyaji 说:
2010年12月20日 06:08

资源跟控制器总是一对一的,也就是每个资源都必须有一个与它相对应的控制器,并且你需要重新理解控制器,现在控制器只是REST接口 的具体实现,它的全部作用就是根据客户的请求返回资源的某种表示(HTML,XML等)。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter
Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee