AI实践哪家强?来 AICon, 解锁技术前沿,探寻产业新机! 了解详情
写点什么

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:591480
用户头像

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

关注

评论

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

EMQ助力阿里云飞天洛神云网络构建新一代“亿级并发、百万级吞吐”NLB网络型负载均衡系统

EMQ映云科技

阿里云 物联网 IoT mqtt 12 月 PK 榜

SpringBoot整合RabbitMQ实现六种工作模式

Jeremy Lai

spring-boot Rabbit MQ

Centos7安装Nginx教程,一步安装http和https

Jeremy Lai

nginx Linux安装

详解MySQL隔离级别

Jeremy Lai

隔离级别

Spring Cloud 整合 nacos 实现动态配置中心

Jeremy Lai

nacos 动态配置

应用瓴羊Quick BI数据分析,实时掌控企业运营数据

对不起该用户已成仙‖

腾讯发布数字政务核心产品体系,多方位助力政府数字化转型

科技热闻

详解HashMap源码解析(上)

Jeremy Lai

HashMap底层原理

SpringBoot快速整合通用Mapper

Jeremy Lai

通用Mapper spring-boot

深入理解Redis 数据结构—字典

Jeremy Lai

字典 redis 底层原理

小程序正式版报错600002 url not in domain list

Jeremy Lai

小程序

模拟HashMap冲突

Jeremy Lai

hashmap 哈希冲突

MySQL更新锁表超时 Lock wait timeout exceeded

Jeremy Lai

事务隔离 Mysql死锁

干货 | 五大关键点,帮助企业快速构建可落地的IT服务管理体系

嘉为蓝鲸

运维 嘉为蓝鲸 IT服务

PID和TID的区别

源字节1号

软件开发 前端开发 后端开发 小程序开发

腾讯云升级云端 IDE Cloud Studio,助力开发“化繁为简”

科技热闻

融云&艾瑞发布《政企数智办公平台行业研究报告》,解读数智化时代的办公新趋势

融云 RongCloud

即时通讯 办公 数智化

Web3时代到来,腾讯云助力产业提效和互联网创新

科技热闻

详解HashMap源码解析(下)

Jeremy Lai

HashMap底层原理

Java通过反射注解赋值

Jeremy Lai

解决问题 java注解

详解ConCurrentHashMap源码(jdk1.8)

Jeremy Lai

ConcurrentHashMap 源码阅读

Seata 环境搭建

Jeremy Lai

分布式事务 seata

Java递归实现评论多级回复

Jeremy Lai

递归 解决方案

中国视频云进入“出海”时代,腾讯云音视频发布海外专门品牌及新产品

科技热闻

五种方式实现 Java 单例模式

Jeremy Lai

设计模式 单例模式

手把手教你用Java获取IP归属地

Jeremy Lai

IP地址

干货 | 企业如何快速采集分析日志?

嘉为蓝鲸

运维 嘉为蓝鲸

阿里云ECS后台CPU占用100%,top却找不到

Jeremy Lai

cpu 100% 阿里云;

字节一面:说说TCP的三次握手

Jeremy Lai

三次握手 TCP协议

后端程序员实现一个IP归属地的小程序

Jeremy Lai

超简单的CDH6部署和体验(单机版)

程序员欣宸

大数据 hadoop CDH 12月月更

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