ruby on rails 3 过滤器的使用

ruby on rails 3的过滤器
参考文档:http://guides.rubyonrails.org/action_controller_overview.html#filters

可以直接定义根过滤器,也就是定义在ApplicationController里
比如
[ccn lang="ruby" tab_size="4" theme="blackboard" width="800" ]
class ApplicationController < ActionController::Base before_filter :require_login private def require_login unless logged_in? flash[:error] = "You must be logged in to access this section" redirect_to new_login_url # halts request cycle end end # The logged_in? method simply returns true if the user is logged # in and false otherwise. It does this by "booleanizing" the # current_user method we created previously using a double ! operator. # Note that this is not common in Ruby and is discouraged unless you # really mean to convert something into true or false. def logged_in? !!current_user end end [/ccn] 也可以直接定义到指定的controller里,方法同上

如何让某些方法例外呢
很简单
[ccn lang="ruby" tab_size="4" theme="blackboard" width="800" ]
class LoginsController < ApplicationController skip_before_filter :require_login, :only => [:new, :create]
end
[/ccn]
上面的意思是在login这个controller里只有new和create方法不需要过滤,其他的都要使用 require_login这个过滤器

什么时候过滤
就像代码里的字面的意思before_filter就是在方法执行前过滤,around_filter就是在执行的前后,中间加上你的方法
比如
[ccn lang="ruby" tab_size="4" theme="blackboard" width="800" ]
# Example taken from the Rails API filter documentation:
# http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html
class ApplicationController < ActionController::Base around_filter :catch_exceptions private def catch_exceptions yield rescue => exception
logger.debug "Caught exception! #{exception}"
raise
end
end
[/ccn]
这是一个抛出异常以后的处理方法
还有after_filter 就是方法执行之后所执行的过滤器了

一个简写形式
[ccn lang="ruby" tab_size="4" theme="blackboard" width="800" ]
class ApplicationController < ActionController::Base before_filter do |controller| redirect_to new_login_url unless controller.send(:logged_in?) end end [/ccn] 过滤器执行顺序
prepend_before_filter ... #优先级最高的前置过滤

过滤器的条件
:only => :index #单一条件
:except => [:foo ,:bar] #多个条件数组方式

需要注意的是,过滤器方法不要被外部访问,定义为private的,把private方法放到最底部,否者controller里原来的方法就会失效了,我之前就出了这个问题,找了半天才发现我把private方法写在了类的顶部,下面的controller方法也没有声明public