写点什么

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

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

关注

评论

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

深度拆解LLM的核心技术栈,助您掌握从模型选型到部署优化的全流程

聚客AI学院

人工智能 agent 大模型落地 AI 智能体 RAG应用

阿里云 API 网关 x OKG:游戏连接治理的「最后一公里」

阿里巴巴云原生

阿里云 云原生 API OKG

Apache Flink 2.1.0: 面向实时 Data + AI 全面升级,开启智能流处理新纪元

Apache Flink

大数据 flink 实时计算 实时计算Flink

通义灵码支持 Qwen3-Coder,带你玩转 Agentic Coding,免费不限量

阿里巴巴云原生

阿里云 AI 云原生 通义灵码

西门子 Smart ECX 与 MyEMS:智慧能碳管理平台的技术路径与生态差异深度解析

开源能源管理系统

开源 能源管理系统

高德开放平台全球LBS服务,MCP Server正式登陆阿里云云市场

高德开放平台

五年磨一剑:Agent 时代追风不如造风

阿里巴巴云原生

阿里云 云原生 AI Agent

合同总是延误?8款好用的电子签章工具推荐给你

数字工具研究

MyEMS 开源能源管理系统:赋能双碳目标的能源数字化基础设施

开源能源管理系统

开源 能源管理系统

为什么选择 BeeWorks Meet?企业会议系统的私有化必要性

BeeWorks

即时通讯 IM 私有化部署

紧急救火与战略开发:软件工程中的关键抉择

qife122

软件工程 技术债务

点击解锁云端新视野:云监控(CES)2025年6月全新升级

华为云开发者联盟

LoongCollector:构建智能时代的数据采集新范式

阿里巴巴云原生

阿里云 云原生 AI Agent

龙蜥受邀参加2025开放计算技术大会,解码基础模型驱动下的系统创新与生态共建

OpenAnolis小助手

开源 AI 操作系统 龙蜥社区

双向闭环驱动精准决策,从战略到单店SKU的无缝链接

第七在线

Django模型迁移指南:从命令用法到最佳实践

电子尖叫食人鱼

扣子可以发布到小米搞钱了!手把手教程来了丨coze开发者瓜分亿级流量池指南

阿星AI工作室

开发者 产品经理 小米 扣子

ToDesk云电脑 vs 顺网云 vs 海马云:谁才是5090显卡云电脑的真王者?

袁袁袁袁满

HGDD 荣耀开发者日丨荣耀小游戏线下沙龙圆满收官

荣耀开发者服务平台

荣耀开发者服务平台 荣耀HONOR 荣耀远航计划 HGDD 荣耀开发者日 荣耀小游戏

2025 WAIC 世界人工智能大会有哪些亮点?

GPU算力

企业私有化即时通讯工具如何选?

BeeWorks

即时通讯 IM 私有化部署

为什么上了ERP系统后,员工效率反而变得更低了呢?

优秀

ERP ERP系统

工程机械行业工具管理破局之战:揭秘RFID智能库房如何终结跨区流转困局

斯科信息

RFID解决方案 RFID工具库房 斯科信息 RFID技术

Agentic AI, 基于 Dify x OceanBase 的实践

老纪的技术唠嗑局

OceanBase 社区版 dify #工作流

通义灵码支持 Qwen3-Coder,带你玩转 Agentic Coding,免费不限量

阿里云云效

阿里云 云原生 通义灵码

喜报!阿里云首批通过 Serverless 云服务能力要求 - 消息队列评估

阿里巴巴云原生

阿里云 Serverless 云原生

Higress 入选《AI Cloud 大模型推理与交互典型案例》

阿里巴巴云原生

阿里云 云原生 Higress

终结警报疲劳!告警分级通知配置实战指南!

华为云开发者联盟

四步破解日志平台数据孤岛困局,核心驱动企业高效运营

日志易

日志管理 日志易

AI+评查,助力烟草企业提质增效

中烟创新

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