写点什么

Rails: 用 Resource_controller 插件给 Controllers 减肥

  • 2008-02-04
  • 本文字数:2561 字

    阅读完需:约 8 分钟

许多Rails大师提倡的一个导向原则是“丰满的模型,精瘦的控制器”。 Rails 控制器只应该包含一些在模型和视图之间周转用的代码。事务逻辑属于模型,而不属于控制器或视图。在如今支持 REST的 Rails 2.0 中,控制器变得非常相象,都包括七个基本的动作(索引、获取、创建、更新、删除、新增和编辑),且具有非常相似的实现方式。在 Rails 2.0 中,可以简单地用 script/generate scaffold standard 来建立控制器框架,即生成了一段具有 REST 特性的控制器代码,如下所示:

class StandardsController < ApplicationController

GET /standards

GET /standards.xml

def index
@standards = Standard.find(:all) respond_to do <span>|</span>format<span>|</span>

format.html # index.html.erb
format.xml { render :xml => @standards }
end
end # GET /standards/1

GET /standards/1.xml

def show
@standard = Standard.find(params[:id]) respond_to do <span>|</span>format<span>|</span>

format.html # show.html.erb
format.xml { render :xml => @standard }
end
end # GET /standards/new

GET /standards/new.xml

def new
@standard = Standard.new respond_to do <span>|</span>format<span>|</span>

format.html # new.html.erb
format.xml { render :xml => @standard }
end
end # GET /standards/1/edit

def edit
@standard = Standard.find(params[:id])
end # POST /standards

POST /standards.xml

def create
@standard = Standard.new(params[:standard]) respond_to do <span>|</span>format<span>|</span>

if @standard.save
flash[:notice] = ‘Standard was successfully created.’
format.html { redirect_to(@standard) }
format.xml { render :xml => @standard, :status => :created, :location => @standard }
else
format.html { render :action => “new” }
format.xml { render :xml => @standard.errors, :status => :unprocessable_entity }
end
end
end # PUT /standards/1

PUT /standards/1.xml

def update
@standard = Standard.find(params[:id]) respond_to do <span>|</span>format<span>|</span>

if @standard.update_attributes(params[:standard])
flash[:notice] = ‘Standard was successfully updated.’
format.html { redirect_to(@standard) }
format.xml { head :ok }
else
format.html { render :action => “edit” }
format.xml { render :xml => @standard.errors, :status => :unprocessable_entity }
end
end
end # DELETE /standards/1

DELETE /standards/1.xml

def destroy
@standard = Standard.find(params[:id])
@standard.destroy respond_to do <span>|</span>format<span>|</span>

format.html { redirect_to(standards_url) }
format.xml { head :ok }
end
end
end

除了特别的名字以外,所有自动生成的控制器代码都是这样的。

使用自动生成的控制器非常简单。在许多情况下,很少或者不需要对生成的代码做任何改变,尤其是当你把“精瘦的控制器”这个理念铭记于心时。

另一方面,Ruby/Rails 还有一条理念,就是 “不要重复自己(DRY)”。 如果存在几乎重复的代码,即便不是你自己写的,也是违背DRY 原则的。

输入: resource_controller。James Golick 贡献了一个新的 rails 插件,称为 resource_controller ,它可以实现与上面同样的控制器,代码如下:

class StandardsController < ApplicationController<br></br>resource_controller<br></br>end然而,这里仍有一个小小的瑕疵。 它没有提供标准的 xml 响应能力,但可以用一小段代码来实现:

class StandardsController < ApplicationController
resource_controller index.wants.xml { render :xml => @standards }

[new, show].each do <span>|</span>action<span>|</span>
action.wants.xml { render :xml => @standard })
end
create.wants.xml { render :xml => @standard, :status => :created, :location => @standard }
[update, destroy].each do <span>|</span>action<span>|</span>
action.wants.xml { head :ok }
end
[create_fails, update_fails].each do <span>|</span>action<span>|</span>
action.wants.xml { render :xml => @standard.errors, :status => :unprocessable_entity }
end
end

有了这个插件,写控制器代码如同写模型代码一样,只需加上像resource_controller这样的声明的类方法,以及action.wants之类的“回调”。这个插件自动为控制器的每个方法分配实例变量。在上面的代码中,给 index 方法分配了 @standards ,给其他方法分配了 @standard。

Rails 有一些公用的模式强迫改变控制器代码。其中包括嵌套资源。很容易在 config/routes.rb 中设置路由:

map.resources :organization, :has_many => :standards但是,一旦你这样做了,你就需要更改控制器来获取和使用上层资源,并在每个动作中正确使用。resource_controller 插件简化了这些。在如上面那样更改路由后,你只需添加一个声明来调用我们的控制器:

class StandardsController < ApplicationController<br></br>resource_controller<br></br>belongs_to :organization<br></br>endbelongs_to 声明允许嵌套资源使用控制器。现在,当一个控制器动作通过嵌套资源 URL 被访问时,例如 /organization/1234 /standards,控制器会自动创建一个名为 @organization 的实例变量,适当地设置好,并使用 standards 所关联地父对象来查找和 建立 Standard 模型的实例。

注意, 同样的控制器也工作在非嵌套的 URL 下,因此我们可以在 routes.rb 中做另一个映射,来允许在 organization 之外访问 starnards:

map.resources :standard<br></br>map.resources :organization, :has_many :standards这样 resource 控制器就会自动地工作在这两种上下文中了。

这个插件也处理命名空间控制器、多态嵌套资源(与 ActiveRecord 多态关联相似和相关)和其他一些奇妙地东西。你也可以获得 URL 以及工作在请求的 URL 上下文中的路径辅助函数。

看来 Resource_controller 是个有用的插件,毫无疑问随着它的成熟,会变得越来越好。细节见 James Golicks 的博客。另外还有 Fabio Akita 制作的一段屏幕录像,演示了这个插件的实际使用情况。

查看英文原文: Rails: Resource_controller Plugin Puts Controllers on a Diet

2008-02-04 20:591620
用户头像

发布了 33 篇内容, 共 67016 次阅读, 收获喜欢 0 次。

关注

评论

发布
暂无评论
发现更多内容

碎片化时间学这些架构知识,月薪20K还不是轻轻松松(1),美团高级java面试题

Java 程序员 后端

程序员一定要会的软件项目管理评估方案,不做只会敲代码的码农!

Java 程序员 后端

程序员入职国企,1周上班5小时,晒出薪资感叹,阿里P8架构师的Java大厂面试题总结

Java 程序员 后端

程序员开发必备22个终端CLI工具也太香了(附下载地址!

Java 程序员 后端

程序员都应当知道的实用工具网站,Java400道面试题通关宝典助你进大厂

Java 程序员 后端

硬肝到秃头!Alibaba强推并发编程笔记我跪了,真的学到好多东西

Java 程序员 后端

碎片化时间学这些架构知识,月薪20K还不是轻轻松松,教你解决线上频出MySQL死锁问题

Java 程序员 后端

神操:凭借“阿里Java脑图,mysql数据库教学视频教程

Java 程序员 后端

立即可用的实战源码(springboot+redis+mybatis,java自学教程免费视频

Java 程序员 后端

算法基础之递归,java核心技术卷

Java 程序员 后端

算法宝典最新分享:Alibaba+小米,redis笔记

Java 程序员 后端

确定要面试问我JVM吗?我打算聊一个小时的!(1),linux驱动架构

Java 程序员 后端

神操:凭借“阿里Java脑图(1),神操作

Java 程序员 后端

算法在哈啰顺风车中的实践应用,netty实战pdf

Java 程序员 后端

类加载器深入剖析,2021最新华为Java校招面试题

Java 程序员 后端

秒懂 Java 的三种代理模式,任小龙java笔记百度云

Java 程序员 后端

程序员就意味着高薪?解除35岁的忧虑,一条正确的职业生涯规划

Java 程序员 后端

程序员面试时这样介绍自己的项目经验,成功率能达到98,华为od技术一面

Java 程序员 后端

文本随机打乱工具

入门小站

工具

确定要面试问我JVM吗?我打算聊一个小时的!,目前最全的《Java面试题及解析》

Java 程序员 后端

算法基础之暴力递归到动态规划,java程序员面试算法宝典pdf猿媛之家

Java 程序员 后端

程序员必知必会之——服务网格istio概念,springboot项目案例百度云

Java 程序员 后端

程序员是如何看待薪资被高估的?内容过于真实,java语言程序设计与数据结构进阶版

Java 程序员 后端

程序员欣宸的文章分类汇总,javaee教程文档

Java 程序员 后端

究竟是什么样的奇葩需求?威胁到程序员的头发,java高级特性编程及实战第三章

Java 程序员 后端

算法入门 - 动态数组的实现(Java版本),分层架构图案例

Java 程序员 后端

硬核!阿里内部这份《Java面试核心知识手册,面经解析

Java 程序员 后端

秋招必备!阿里产出的高并发+JVM套餐,mybatis总结

Java 程序员 后端

秒懂数组拷贝,感知新境界,java编程思维百度云

Java 程序员 后端

[架构实战营]模块二作业:微信朋友圈高性能复杂度架构

Geek_99eefd

架构实战营

秀儿!用SSM框架实现了支付宝的支付功能,神操作啊,大型分布式系统架构图

Java 程序员 后端

Rails: 用Resource_controller插件给Controllers减肥_Ruby_Rick DeNatale_InfoQ精选文章