Ruby on Rails 中文 Wiki
Rails2_0新特性_Activesource中的Custom_method

近日 Active Resource? 进行了重大升级,使其不必通过后台URI的支持即可以激活custom method。令我感到非常激动的不仅仅是自己对 ARes1 的热爱,也是因为这是我在 Rails Hackfest活动 提交的补丁之一。当初提交的代码中仍有许多不确定的地方,所以我自己也不太清楚它是否能被采纳。值得感谢的是,它被采取了。那么关于我就说到这儿,下面让我们一起来谈谈你。

说道您已经拥有一个具备REST结构的网络服务。它具备着您为 Person资源 所准备的建立在CRUD之上的action,包括几个特别的 custom method,例如 promote, deactivate 和一个定制搜集method: sort。如果没有来自ARes的custom method支持,您就得亲手建立起您所需要的URI,并且要亲自设定用来激活method的http连接。

的确,这样做比较累人。下面进入custom method支持。

首先假设有下得到支持的远程服务:

# Collection custom method
GET /people/sorted.xml?by=sort_field

# Element custom methods
PUT /people/1/promoted.xml?position=position_name
DELETE /people/1/deactivated.xml

这里是我们简单定义的 ARes Person 类:

class Person < ActiveResource::Base
  self.site = "http://mypeeps.com/" 
end

ARes里激活定制method的格式其实蛮简单的。只需要在类2 或对象实体3 使用get, post, put或delete之一4 来组成您需要的http method。将需要激活的定制method名称作为第一个实参(argument),其他需要输入的形参(parameter)放到一起作为第二个实参(argument)。让我为上述恼人的描述举个例子:

既然已经拥有美妙的远程REST服务,我们可以:

Active Resource? Collection Custom Method Calls

我们使用collection call来针对资源collection。简单来说,collection call可以是任何一个不对当前资源进行操作的method call。它们的URI并不涉及资源id,使得它们能够得到简便的维护。

一个定制的method call不属于您通过设置RESTFUL路由后直接得到的CRUD 行为。在我们的示例中,我们有一个叫做sorted 的 collection custom method。这个method输出针对个别域搜索资源而得到的结果。5

远程服务支持下面的URI:

# Collection custom method
GET /people/sorted.xml?by=sort_field

下面是如何通过 ARes1 激活定制method:

# 获取按照名字排列的职员列表
people = Person.get(:sorted, :by => 'first_name') # =>
   # GET /people/sorted.xml?by=first_name

如果您的公司经营变得困难,而且您有一个被远程服务支持的使用put方法的 layoff REST 行为,下面是您的表达式:

# 解雇所有人
Person.put(:layoff) # => PUT /people/layoff.xml

希望现在您已经了解首先需要通过ARes1类激活使用远程服务的Http方法,并使用custom method的名称作为第一个实参(:layout)。非常简单。针对类使用的 custom method 被称为 collection method (由于它不引用已经存在的资源6 ),并且为资源集建立了合适的 URI

Active Resource? Element Custom Method Calls

如果您需要操作某一特定的资源,您将需要激活element call。在ARes1中, collection custom method 与 element custom method 之间唯一的区别在于 使用element call的时候,您所操作的对象是 ARes model 的一个实体。被建立的URI则参照特定的资源而进行调整。在我们的示例中:

远程服务现在支持下面的URI:

# 通过 Element custom method 使某人晋升到指定的职位
PUT /people/1/promoted.xml?position=position_name

下面是您如何通过 ARes 激活这个method:

# 提升我们的明星开发员
ryan = Person.find(1)
ryan.put( :promoted, :position => 'Manager')  # 嗯。。这对我是真正的提升吗??
    # PUT /people/1/promoted.xml?position=Manager

远程服务需要的是同 PUT http方法 一同使用的晋升方法 (promoted call),所以您唯一需要做得是在即将得到晋升的 Person 实体上激活 PUT 方法,以及包括了晋升细节的 hash 数组。同样,对于删除 (delete):

在服务器上:

DELETE /people/1/deactivated.xml

在 ARes 中…

# 结果他变得非常非常受欢迎 (不能留他在这里了)
ryan = Person.find(1)
ryan.delete( :deactivated)  # DELETE /people/1/deactivate.xml

后记

值得一提的一件事是除了 GET 以外所有 custom method call 都会输出来自远程服务的回应。您可以根据这些回应代码来设置您自己的回应。GET 输出一个 hash数组7 ,这个数组用来表达 来自远程服务的XML数据。如果您需要通过 GET 获取实际的对象,可以使用 FIND 方法并输入一个符号:

# 获取所有的经理 (managers)
Person.get( :managers) #=> [{:name => "Ryan"}, {:name => "David"}]
Person.find( :managers) #=> <#Person...><#Person ...>
   #=> GET /people/managers.xml

Active Resource? 的 custom method,现在是你的了

注脚:

  1. Active Resource本身,文中皆简称 ARes
  2. 针对定制搜集的method
  3. 上面提到的特殊定制的methods
  4. 也被称之为http动词,译者注
  5. 在我原先提交的示例中叫做sort,后来经DHH建议修改为形容词sorted。您会发现这样做是为了使URI以及ARes1 表达式读起来更加接近琅琅上口的句子
  6. 已经被记录在数据库的资源:
    person = Person.new # person is NOT an existing resource
    person.save #=> true # person IS an existing resource
    

    谢谢 Ryan 的例子!
  7. [{1=>”Ryan” },{2=>”David”}]

感谢 Yudi 提供本系列文档

原文作者是 Ryan Daigle, 请访问他的博客

本条目被以下条目链接: