写点什么

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

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

关注

评论

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

Java面试为什么对源码的考察越来越看重?

了不起的程序猿

程序员 后端 架构师 java面试 多线程源码

使用AI机器学习,轻松解决化合物配比优化问题

Altair RapidMiner

人工智能 AI 数据分析、 工业化设计 altair

为什么你用的 MyBatis 慢?一行配置让它性能翻倍!

快乐非自愿限量之名

mybatis

企业的海外网络访问需求怎么解决?

Ogcloud

SD-WAN SD-WAN组网 SD-WAN国际专线 海外网络访问 海外网络连接

奇奇怪怪的编程语言:Malbolge

不在线第一只蜗牛

编程语言

焱融全闪 F9000X 打造英智创新先进智算平台 训推效能倍增

焱融科技

大模型 智算中心 全闪存储 英智创新 智能算力

Java程序员如何高效学习Spring全家桶?

了不起的程序猿

spring 程序员 java程序员 java面试 八股文

【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(8)

HarmonyOS SDK

harmoyos

客户服务新突破,天润融通助力电动车企业实现数智化转型

天润融通

Transmit 5 for Mac(强大的FTP客户端)中文版

Mac相关知识分享

CDN加速:优化网站服务器访问速度

Ogcloud

CDN 网络加速 CDN加速 网络加速服务 CDN网络加速

AutoMQ x Iceberg SG Meetup: Table Topic 新特性统一流与分析首次公开

AutoMQ

云计算 kafka iceberg 活动预告 AutoMQ

园区数字化管理系统(源码+文档+部署+讲解)

深圳亥时科技

浅谈CAF云应用框架

inBuilder低代码平台

框架 构架 云应用

2024全球人形机器人领域深度调研和行业前瞻报告

机器人头条

特斯拉 大模型 人形机器人 具身智能

威睿三电全面开花,助力极氪问鼎销冠

科技热闻

天润融通:为国内外行业巨头提供定制化IT Service解决方案

天润融通

Java高并发系统设计核心知识全解

了不起的程序猿

程序员 后端 高并发 架构师 Java高并发

(Vue3结合ThreeJS开发3D)在线三维CAD中加载和保存STEP模型

WEB CAD SDK

[Java] Stream流使用最多的方式

EquatorCoco

Java Python

如何以MLOps保障时效表达稳定性|得物技术

得物技术

算法 供应链

MATLAB R2020b for Mac(商业数学软件)中文版

Mac相关知识分享

Carbon Copy Cloner for Mac(磁盘克隆/同步/备份软件)

Mac相关知识分享

Reallusion Cartoon Animator for Mac(2D动画设计制作软件)中文版

Mac相关知识分享

微信公众号设置关键词回复、自动回复、关注回复、卡密回复平台使用手册

木偶

微信 Web 卡密

【C++】static 知识整理 【静态与局部静态】

快乐非自愿限量之名

c++

MyZip Pro for Mac(专业解压缩工具)

Mac相关知识分享

IoTDB 能源电力解决方案:协助“源网储”数字化智能化转型,构建高质量新型电力系统

Apache IoTDB

ZOC8 for Mac(终端仿真软件)

Mac相关知识分享

一座重庆工厂,智能与制造的“两江之约”

脑极体

AI

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