- 浏览: 2690725 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
-
80后的童年2:
深入浅出MongoDB应用实战开发网盘地址:https://p ...
MongoDB入门教程 -
shliujing:
楼主在不是精通java和php的前提下,请不要妄下结论。
PHP、CakePHP哪凉快哪呆着去 -
安静听歌:
希望可以一给一点点注释
MySQL存储过程之代码块、条件控制、迭代 -
qq287767957:
PHP是全宇宙最强的语言!
PHP、CakePHP哪凉快哪呆着去 -
rryymmoK:
深入浅出MongoDB应用实战开发百度网盘下载:链接:http ...
MongoDB入门教程
我们上次看过了ActiveRecord的callbacks,这次看看ActionController的filters
1,filter继承
先执行父类中的filter,再执行子类中的filter,如果父类中的filter返回false,则不执行子类中后续的filter
2,filter类型
1)method reference(symbol)
2)external class
3)inline method(proc)
3,filter链的执行顺序
可以使用prepend_before_filter、prepend_after_filter和prepend_around_filter来让某些filter最先执行
现在filter的执行顺序为:ensure_items_in_cart -> :ensure_items_in_stock -> :verify_open_shop
4,Around filters
5,filter链skipping
6,filter conditions
7,filter chain halting
对于如下filter定义:
执行顺序为:
如果#before返回false,则第二个#around和#after仍会执行
源代码文件为filters.rb:
代码一目了然,十有八九能猜到,使用alias_method_chain给perform_action/process/process_cleanup加上filter
perform_action_with_filters -> call_filter -> filter.call -> BeforeFilterProxy.call || AfterFilterProxy.call || proxy_before_and_after_filter
其他则为一些增删改filter_chain的public方法,如before_filter、after_filter、around_filter、skip_filter等
1,filter继承
先执行父类中的filter,再执行子类中的filter,如果父类中的filter返回false,则不执行子类中后续的filter
2,filter类型
1)method reference(symbol)
class BankController < ActionController::Base before_filter :audit end
2)external class
class OutputCompressionFilter def self.filter(controller) controller.response.body = compress(controller.response.body) end end class NewspaperController < ActionController::Base after_filter OutputCompressionFilter end
3)inline method(proc)
class WeblogController < ActionController::Base before_filter { |controller| false if controller.params["stop_action"] } end
3,filter链的执行顺序
可以使用prepend_before_filter、prepend_after_filter和prepend_around_filter来让某些filter最先执行
class ShoppingController < ActionController::Base before_filter :verify_open_shop end class CheckoutController < ShoppingController prepend_before_filter :ensure_items_in_cart, :ensure_items_in_stock end
现在filter的执行顺序为:ensure_items_in_cart -> :ensure_items_in_stock -> :verify_open_shop
4,Around filters
class SomeController < ActionController::Base around_filter :catch_exceptions private def catch_exceptions yield rescue => exception logger.debug "Caught exception! #{exception}" raise end end
5,filter链skipping
class ApplicationController < ActionController::Base before_filter :authenticate around_filter :catch_exceptions end class SignupController < ApplicationController # Skip :authenticate, run :catch_exceptions. skip_before_filter :authenticate end
6,filter conditions
class Journal < ActionController::Base before_filter :authorize, : only => [:edit, :delete] around_filter :catch_exceptions, :except => [:foo, :bar] end
7,filter chain halting
对于如下filter定义:
class SomeController < ActionController::Base before_filter :be around_filter :ar after_filter :af end
执行顺序为:
# ... # . \ # . #around (code before yield) # . . \ # . . #before (actual filter code is run) # . . . \ # . . . execute controller action # . . . / # . . ... # . . / # . #around (code after yield) # . / # #after (actual filter code is run)
如果#before返回false,则第二个#around和#after仍会执行
源代码文件为filters.rb:
module ActionController module Filters def self.included(base) base.extend(ClassMethods) base.send(:include, ActionController::Filters::InstanceMethods) end module ClassMethods def append_before_filter(*filters, &block) append_filter_to_chain(filters, :before, &block) end alias :before_filter :append_before_filter def append_after_filter(*filters, &block) prepend_filter_to_chain(filters, :after, &block) end alias :after_filter :append_after_filter def prepend_before_filter(*filters, &block) prepend_filter_to_chain(filters, :before, &block) end def prepend_after_filter(*filters, &block) append_filter_to_chain(filters, :after, &block) end def append_around_filter(*filters, &block) filters, conditions = extract_conditions(filters, &block) filters.map { |f| proxy_before_and_after_filter(f) }.each do |filter| append_filter_to_chain([filter, conditions]) end end alias :around_filter :append_around_filter def prepend_around_filter(*filters, &block) filters, conditions = extract_conditions(filters, &block) filters.map { |f| proxy_before_and_after_filter(f) }.each do |filter| prepend_filter_to_chain([filter, conditions]) end end def skip_before_filter(*filters) skip_filter_in_chain(*filters, &:before?) end def skip_after_filter(*filters) skip_filter_in_chain(*filters, &:after?) end def skip_filter(*filters) skip_filter_in_chain(*filters) end class Filter def call(controller, &block) raise(ActionControllerError, 'No filter type: Nothing to do here.') end end class FilterProxy < Filter def filter @filter.filter end def around? false end end class BeforeFilterProxy < FilterProxy def before? true end def call(controller, &block) if false == @filter.call(controller) controller.halt_filter_chain(@filter, :returned_false) else yield end end end class AfterFilterProxy < FilterProxy def after? true end def call(controller, &block) yield @filter.call(controller) end end class SymbolFilter < Filter def call(controller, &block) controller.send(@filter, &block) end end class ProcFilter < Filter def call(controller) @filter.call(controller) rescue LocalJumpError raise(ActionControllerError, 'Cannot yield from a Proc type filter. The Proc must take two arguments and execute #call on the second argument.') end end class ProcWithCallFilter < Filter def call(controller, &block) @filter.call(controller, block) rescue LocalJumpError raise(ActionControllerError, 'Cannot yield from a Proc type filter. The Proc must take two arguments and execute #call on the second argument.') end end class MethodFilter < Filter def call(controller, &block) @filter.call(controller, &block) end end class ClassFilter < Filter def call(controller, &block) @filter.filter(controller, &block) end end protected def append_filter_to_chain(filters, position = :around, &block) write_inheritable_array('filter_chain', create_filters(filters, position, &block) ) end def prepend_filter_to_chain(filters, position = :around, &block) write_inheritable_attribute('filter_chain', create_filters(filters, position, &block) + filter_chain) end def create_filters(filters, position, &block) filters, conditions = extract_conditions(filters, &block) filters.map! { |filter| find_or_create_filter(filter,position) } update_conditions(filters, conditions) filters end def find_or_create_filter(filter,position) if found_filter = find_filter(filter) { |f| f.send("#{position}?") } found_filter else f = class_for_filter(filter).new(filter) case position when :before BeforeFilterProxy.new(f) when :after AfterFilterProxy.new(f) else f end end end def class_for_filter(filter) case when filter.is_a?(Symbol) SymbolFilter when filter.respond_to?(:call) if filter.is_a?(Method) MethodFilter elsif filter.arity == 1 ProcFilter else ProcWithCallFilter end when filter.respond_to?(:filter) ClassFilter else raise(ActionControllerError, 'A filters must be a Symbol, Proc, Method, or object responding to filter.') end end def skip_filter_in_chain(*filters, &test) filters, conditions = extract_conditions(filters) filters.map! { |f| block_given? ? find_filter(f, &test) : find_filter(f) } filters.compact! if conditions.empty? delete_filters_in_chain(filters) else remove_actions_from_included_actions!(filters,conditions[: only] || []) conditions[: only], conditions[:except] = conditions[:except], conditions[: only] update_conditions(filters,conditions) end end def proxy_before_and_after_filter(filter) return filter unless filter_responds_to_before_and_after(filter) Proc.new do |controller, action| unless filter.before(controller) == false begin action.call ensure filter.after(controller) end end end end end module InstanceMethods def self.included(base) base.class_eval do alias_method_chain :perform_action, :filters alias_method_chain :process, :filters alias_method_chain :process_cleanup, :filters end end def perform_action_with_filters call_filter(self.class.filter_chain, 0) end def process_with_filters(request, response, method = :perform_action, *arguments) @before_filter_chain_aborted = false process_without_filters(request, response, method, *arguments) end def filter_chain self.class.filter_chain end def call_filter(chain, index) return (performed? || perform_action_without_filters) if index >= chain.size filter = chain[index] return call_filter(chain, index.next) if self.class.filter_excluded_from_action?(filter,action_name) halted = false filter.call(self) do halted = call_filter(chain, index.next) end halt_filter_chain(filter.filter, :no_yield) if halted == false unless @before_filter_chain_aborted halted end def halt_filter_chain(filter, reason) if logger case reason when :no_yield logger.info "Filter chain halted as [#{filter.inspect}] did not yield." when :returned_false logger.info "Filter chain halted as [#{filter.inspect}] returned false." end end @before_filter_chain_aborted = true return false end end end end
代码一目了然,十有八九能猜到,使用alias_method_chain给perform_action/process/process_cleanup加上filter
perform_action_with_filters -> call_filter -> filter.call -> BeforeFilterProxy.call || AfterFilterProxy.call || proxy_before_and_after_filter
其他则为一些增删改filter_chain的public方法,如before_filter、after_filter、around_filter、skip_filter等
发表评论
-
用了TextMate才知道什么叫神级Editor
2011-03-09 04:51 58020一直用Eclipse作为开发Ruby和Java项目的IDE,但 ... -
Ruby使用OAuth登录新浪微博和豆瓣
2011-01-09 12:49 4495首先需要安装oauth这个gem包 gem install ... -
使用Passenger+nginx部署Rails
2010-12-28 15:12 50551. Install Passender gem instal ... -
markItUp+rdiscount搭建Rails下可视化Markdown编辑器
2010-12-21 17:48 5491markItUp是基于jQuery的可视化编辑器,支持Html ... -
Rails3 and MongoDB Quick Guide
2010-12-10 14:13 2773Install MongoDB Download: http: ... -
基于ruby-protobuf的rpc示例
2009-08-11 11:51 41671, 安装ruby-protobuf gem instal ... -
Ruby导出xls和csv的utf-8问题的解决
2009-02-04 15:05 6879数据库数据为utf-8格式,包括中文和拉丁文等等 导出文件xl ... -
URL/HTML/JavaScript的encode/escape
2009-01-04 13:03 9373最近经常被URL、HTML、JavaScript的encode ... -
各种排序的Ruby实现
2008-11-27 14:51 4020Θ(n^2) 1, Bubble sort def bu ... -
12月5日北京RoR活动!
2008-11-26 18:38 3029又是一年过去了,Rails在国内的发展势态良好,很多使用RoR ... -
Rails程序开发的最大问题是代码规范
2008-08-28 11:56 5657使用Rails开发大型复杂B2B应用一年了,这个项目目前开发人 ... -
Web开发大全:ROR版——推荐序
2008-07-09 00:39 2438来自http://www.beyondrails.com/bl ... -
深入ActionMailer,使用Sendmail发邮件
2008-07-03 11:41 3408来自: http://www.beyondrails.com/ ... -
Rails里如何结合ExceptionNotification配置gmail账户发邮件
2008-06-19 19:56 31241,安装ExceptionNotification rub ... -
使用coderay和railscasts样式进行代码高亮
2008-06-17 00:16 2414CodeRay是一个语法高亮的Ruby库,效率很不错。 Cod ... -
Capistrano试用
2008-06-16 19:05 19741,客户端机器安装Capistrano gem insta ... -
lighttpd真垃圾啊
2008-06-04 18:38 2562使用lighttpd+fcgi跑Rails程序,文件上传会si ... -
将gem变成plugin
2008-06-04 11:27 1826有什么样的需求就有什么样的对策 当vhost上的帐号没有ge ... -
在Rails里使用ReCaptcha添加验证码
2008-06-03 15:51 42891,去http://recaptcha.net/sign up ... -
Rails里给文件上传添加progress_bar
2008-05-27 17:00 2113文件上传很慢时,UI没有什么用户提示,这样让人很费解,所以我们 ...
相关推荐
Rails::API 移除了 ActionView 和其他一些渲染功能,不关心Web前端的开发者可更容易、快速地开发应用程序,因此运行速度比正常的 Rails 应用程序要快。 Rails::API 可以用来创建只提供API服务(API-Only)的 Rails ...
使用 Rails 4 的简单聊天应用程序 - ActionController::Live 应用组件: 1 . 使用 Rails 4 ActionController::Live 的聊天应用程序 2 . 基本 LDAP 身份验证 3 . Redis 服务器集成 4 . 彪马服务器 1 . Rails 4 ...
1. Rails 3.0: Rails 3是重大升级,引入了ActionController::Metal,这是一个轻量级的控制器,用于提高性能。同时,它引入了多路由引擎支持,如Rack中间件,使得与其他Web服务器的集成更加容易。此外,ActiveRecord...
在Ruby on Rails(Rails)框架中,开发人员经常需要实现各种用户交互功能,例如三级联动选择,这在处理如中国省市区这样的地理数据时尤其常见。这篇博客文章“Rails中应用Ext.tree:以中国的省市地区三级联动选择为...
《Rails Exporter 源码解析》 Rails Exporter 是一个用于 Rails 应用程序的开源工具,主要用于数据导出功能。源码分析将帮助我们深入理解其内部工作原理,以便更好地利用它来优化我们的应用。 一、Rails 框架基础 ...
这个Rails项目提供了学习和研究Web开发的机会,特别是对于Ruby on Rails新手,可以通过阅读和理解源代码来提升技能,了解实际应用中Rails的用法。同时,对于有经验的开发者,这个项目也可以作为一个起点,进行二次...
Ruby on Rails,简称Rails,是基于Ruby语言的开源Web应用框架,它遵循MVC(Model-View-Controller)架构模式,旨在使开发过程更加简洁高效。这个“ruby on rails 教程源码”很可能是为了辅助学习者深入理解Rails的...
《Rails 3 in Action》是2011年由Ryan Bigg撰写的一本关于Ruby on Rails框架的权威指南,专门针对当时最新的Rails 3.1版本进行了深入解析。这本书旨在帮助开发者充分利用Rails 3.1的强大功能,提升Web应用开发的效率...
Rails :: Controller :: Testing 这个gem将assigns给控制器测试的内容以及assert_template带回assigns控制器和集成测试的内容。 这些方法已中。 安装 将此行添加到您的应用程序的Gemfile中: gem 'rails-...
本书源码 博文链接:https://msnvip.iteye.com/blog/139752
《深入解析bhl_rails_solr源码》 在当今的Web开发领域,Rails框架以其高效、简洁的设计理念,深受开发者喜爱。同时,Solr作为一款强大的全文搜索引擎,被广泛应用于各类复杂的数据检索场景。当这两者结合时,便诞生...
Rails的许多特性,如ActiveRecord(ORM)、ActiveModel、ActionController和ActionView,都是为了支持这种分层架构。 压缩包中的`seanatnci-rails_space-53c56b4`可能是一个具体的Rails项目仓库,包含以下关键组成...
标题中的“Web开发敏捷之道--应用Rails进行敏捷Web开发 之 Depot代码”表明这是一个关于使用Ruby on Rails框架进行敏捷Web开发的示例项目,名为Depot。Ruby on Rails(简称Rails)是一个开源的Web应用程序框架,它...
2. **ActionController**:负责处理HTTP请求,并将数据转发给相应的模型和视图。它管理着应用的业务逻辑和控制流程。 3. **ActionView**:负责生成HTML或其他类型的响应,通常与模板系统一起工作,将数据以用户友好...
Ruby on Rails,简称Rails,是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本篇将通过一个入门实例,深入探讨Rails的基本概念和核心...
通过研究这个源码,你可以深入理解Rails的工作原理,学习如何设计和实现社区网站的核心功能,如用户注册、论坛讨论、个人资料管理等。同时,这也是一个绝佳的机会去实践敏捷开发和TDD(测试驱动开发)原则,提升你的...
为了帮助读者更好地理解和应用所学知识,**Rails 4 in Action, 第二版** 包含了一系列案例研究和实战项目,例如: - **电子商务网站开发**:从零开始构建一个完整的电子商务平台,涵盖商品管理、订单处理等功能。 -...
压缩包子文件的文件名称 "Ruby on Rails.pptx" 提示可能是一个关于Rails的PowerPoint演示文稿,其中可能涵盖了Rails的基础概念、安装步骤、主要组件介绍、开发流程、最佳实践,以及可能的示例代码和案例研究。...
Ruby on Rails(简称Rails)是一种基于Ruby编程语言的开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,旨在提高开发效率和可读性。Rails的哲学强调“约定优于配置”和“Don't Repeat Yourself”(DRY...