写点什么

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

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

关注

评论

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

【Flutter 专题】90 图解 Dart 单线程实现异步处理之 Future (一)

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 7月日更

以产业区块链提升数字化转型质量

CECBC

架构实战营 模块二作业

孫影

架构实战营 #架构实战营

Javascript 的工作原理:引擎、运行时和调用堆栈概述

devpoint

JavaScript V8 7月日更

Python OpenCV 之图像金字塔,高斯金字塔与拉普拉斯金字塔

梦想橡皮擦

7月日更

市场总局禁止虎牙斗鱼合并:抵制互联网行业垄断行为

石头IT视角

你以为的你以为未必是你以为的

Bruce Talk

敏捷 随笔 Agile 引导和教练

区块链+游戏资产所有权,将如何激活游戏经济的发展?

CECBC

7款神器,让程序员幸福感暴增!

Jackpop

京东智造云:在世界人工智能大会上,听到的工业智能生长的声音

脑极体

模块一作业

Always

架构实战营

Apache Flink 漫谈系列 —— 概述

云祁

flink 7月日更

Hadoop 入门教程

若尘

大数据 hadoop

10条让开发者受益终生的编码原则

Jackpop

密码你真的了解吗

卢卡多多

7月日更

网络攻防学习笔记 Day71

穿过生命散发芬芳

网络攻防 7月日更

高性能架构

编号94530

Java 架构设计 高性能

一文掌握Java TreeMap与HashMap

Jackpop

PowerShell 正则表达式

耳东@Erdong

PowerShell 7月日更

🏆【CI/CD技术专题】「Maven插件Docker系列」使用Maven插件构建Docker镜像的方法

洛神灬殇

Docker maven 7月日更 Plugin

性能测试框架对比初探

FunTester

性能测试 接口测试 测试框架 测试开发

性能框架哪家强—JMeter、K6、locust、FunTester横向对比

FunTester

性能测试 接口测试 测试框架 测试开发

架构实战训练营 - 模块八课后作业

Johnny

架构实战营

Goroutine 是如何运行的

Rayjun

调度器 Go 语言

实时音视频技术全栈攻略|寻找C站宝藏

liuzhen007

音视频 7月日更

Go 学习笔记之 结构体

架构精进之路

Go 语言 7月日更

Facebook工程经验--PCIe故障监控和修复

俞凡

架构 大厂实践

智能重排序在推荐场景中的应用(三十四)

Databri_AI

推荐系统 排序 智能

模块八作业

Presley

领域驱动设计到底在讲什么?

escray

学习 极客时间 7月日更 如何落地业务建模

Redis - Cluster - 源码阅读(二)

旺仔大菜包

redis

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