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