aardvark 写道
最近一直在补Ruby,心里惦记着Rails1.2但是一直没有时间去细看。昨天看了DHH的"Discovering a world of Resources on Rails",再来看楼主这个发帖,发现楼主对这个例子本身的理解有些不完整,对RESTful的理解也有偏差。
楼主的例子看似和DHH的例子很像,但实际很不同。DHH的例子是User/Group,典型的use case是“管理员把某个用户添加到某个组”。这样的例子,从Model到Controller到View恰好是完整的一套,很清晰也很优美。这里User是操作的对象。
而User/Article的例子中,这个User是操作的对象,同时又是操作的主体。一个可能是use case是“用户标记某文章为‘已读’”,但更典型的use case是“当用户阅读某篇文章的同时,标记‘已读’”。这里面同时有两个操作:1)用户阅读文章 2)标记‘已读’(或者说删除‘未读’)。这个例子比User/Group的例子要复杂得多。
其实在DHH的讲演里面提到了这样的例子(恰恰是说“例外”的时候)。我想要在此引用一下DHH的一句话:
引用
CRUD is not a goal,it’s an aspiration,a design technique
CRUD不是一个目标,而是一种精神,一种设计技巧
这句话之后DHH就举了个不用CRUD的例子:Kase。Kase的例子是说,当用户close一个Kase的时候,同时建立一个Closure来保存谁、什么时间关闭了Kase。
当然,这个例子和楼主的例子也是有区别的。楼主的例子里面,阅读一篇文章并不修改文章本身,而关闭一个Kase要修改Kase本身;但是共同点是,都同时涉及到两个Controller。DHH把这种情况当作aspect/view来看:
POST /kases/1;close
POST /identity;aspect
DHH的例子是:
class KasesController < ActionController::Base
# POST /kases/1;close
def close
@kase.close!
redirect_to :action=>"show"
end
end
class ClosuresController < ActionController::Base
def create
Closure.create!(:kase=>@kase, :closer=>@user
redirect_to(kase_url(@kase))
end
end
目前我还不知道Rails1.2中怎样同时用两个Controller。另外我很感兴趣的是,如果这两个Controller做的事需要是transactional的,即或者都成功或者都不成功,rails有没有这样的支持(在一个Controller中当然没有问题,但分散到两个Controller的话rails还能实现transactional吗)。从这个角度来看,我甚至严重怀疑DHH的这个例子是否恰当!
从楼主的代码看,只支持“用户标记某篇文章为‘已读’”,而不能支持用户阅读的同时标记,所以我说这不是个好例子。
看完了DHH那个presentation,我以为Rails1.2的RESTful最闪亮的点是通过ActiveResource提供了漂亮的、简单的系统间(或者系统的不同部分之间)的交互。RESTful绝不仅仅是CRUD,CRUD只是达到RESTful的手段而已。在一般情况下,CRUD精神能简化设计,但CRUD不应得到过分的强调,更不是RESTful的精髓。KasesController::close已经告诉我们"CRUD is everything"这种想法是错误的。
另外,如果在一个系统内部为了RESTful而RESTful,并不能获得RESTful的好处却带来设计及实现上的麻烦,也是不可取的。
谢楼上的思考,我也把"Discovering a world of Resources on Rails"重看了一遍,我认为楼主的做法是正确的,只是他没说清楚一些定义而已。
RESTful核心就是资源,把关系也看作是资源,所以用户加入和退出组可以改成用户与组的关系这个资源的创建和删除。基于这一点我觉得RESTful应该翻译为REST风格,不给它个合适的中文词汇来代替,总是理解起来有些偏差。这一点楼主的例子也是合适的。
你说的Kase那部分实际上DHH提到了3种做法(技巧)[注],而不是说KasesController#close和 ClosuresController#create要分别调用,既然创建了Closure,它里面就包含created_at,这和kase里的 closed_at不是同一个意思吗?何必还更新kase对象呢?所以根本没有事务要考虑,你“甚至严重怀疑DHH的这个例子是否恰当”,我觉得是没理解这个部分。
注:这3种做法,第1种是我们现在用的,scaffold产生的代码就是这种。第2种是把关系转成资源来创建。第3种是用has_one。这3种分别对应到他前面所说的事件、关系、状态。
分享到:
相关推荐
应用Rails进行REST 开发 ,翻译自《RESTful Rails Development》
RESTful-Rails-开发 RESTful Rails 开发库。 你好 Rails 类别图 API - WIKICAT 本地图片 带有地理标记的维基百科文章 - WIKIPINS 城市步道API 余烬漫步
How to RESTful rails
Presentation on advanced restful rails application
使用ROR进行REST风格的网络应用开发的教程。
RestFul_Rails_Dev_v_0.1 RestFul_Rails_Dev_v_0.1
Ruby on Rails打造企业级RESTful API项目实战我的云音乐
todos-api(带有Rails 5的RESTful JSON API) 此仓库是@ scotch-io教程系列的源代码伴侣, ---请注意我选择暂时存档此存储库,因为我没有足够的带宽来照顾传入的问题和请求。 该教程仍然有效,并且在评论部分仍然是...
RESTful.Rails.Development.2015.10.pdf
versionist一个用于对基于Rails的RESTful API进行版本控制的插件。 Versionist开箱即用地支持三种版本控制策略:通过HTTP标头指定版本通过在路径之前添加版本标记来指定版本versionist一个用于对基于Rails的RESTful ...
Ruby on Rails中文指南
一个准系统、无状态、RESTFUL Rails JSON API 服务器,遵循当前的最佳实践,专注于安全性。 细节 使用 Rails 的内置进行身份验证,使其最小化、记录良好且易于升级 无状态 JSON API - 没有不安全的会话或 cookie,...
Rails Api基地 介绍 该项目的目标是: 一个讨论Rails设置和开发的api示例。 从其开始项目的基本模板。 规格摘要: RESTful API。 api版本。 Notes应用示例。 模式和良好做法。 用户管理。 版本到期。 国际...
除了设置以外,还添加了其他设置,并最初配置了有用的Gems,这些资源通常在Rails堆栈应用程序中使用。产品特点 安装过程要求基于Docker容器的样板。 要开始使用它们,首先,我们必须确保已安装Docker Engine和...
本书的目标是成为对“如果想学习使用 Ruby on Rails 进行 Web 开发,我应该从哪儿开始?”这一问题的最好答案。学习完本书的内容之后,你将具备使用 Rails 进行开发和部署 Web 程序的技能。同时你还能够通过一些进阶...
应用Rails进行REST开发.pdf Restful Rails Development
web开发敏捷之道的原书Agile Web Development With Ruby On Rails第一及第二版
Ruby On Rails中文教材(PDF)
rails指南 中文版
·包含RESTful Web services的真实案例,如Amazon的简单存储服务与Atom发布协议等 ·探讨各种流行编程语言的Web services客户端 ·展示如何用三种流行框架实现RESTful services —— Ruby on Rails、Restlet(基于...