页面有些函数,有些是用户是否登录都可以用,有些是必须登录。比如:
before_filter :find_user, :only => [:a,:b,:c,:d]
def find_user @user = User.find_by_id(session[:user_id]) if !@user redirect_to(:controller=>"welcome",:action => "index") end end
其中:a,:b 可以不登录就能使用,如果在 find_user 里直接判断 session,如果不存在就认为是合法的,会影响到:c,:d 的使用。。这样情况下该怎么做?before_filter 支持多个 :find_user 这种做法吗?
偶一般需要登陆的会放到下一级的域 比如/admin 那么,/admin/orders,我就会在 admin 这级的 controller 都继承 admin_controller,然后 before_filter 验证必须登陆。 而,某些 admin 下不需要登陆,就:except 咯。 如果你设计的层次设计得好,这些实现会很轻松。。。
一个方法只做一件事,且仅仅只做一件事,使一个方法成为最小的一个单元。 http://yunshuisuiyuan.iteye.com/blog/1561179
如果你需要检测权限,find_user 这个方法名不是一个很好的选择,从 find_user 意思来说,它的职责只是用来查找一个用户,给之后的 action 用. 用两个过滤器,过滤器是按写的顺序执行的。你可以先写一个过滤器查找用户,再写一个过滤器检查权限。
权限检查可以参考 typo 博客,个人觉得很不错https://github.com/fdv/typo/blob/master/vendor/plugins/typo_login_system/lib/login_system.rb current_user 方法拿到当前登录用户 logged_in?检测是否登录 login_required 提供给过滤器使用,没有登录的用户跳转到登录页面
#6 楼 @help5305fff 不登陆是说,他可以浏览这个页面内容;如果他登陆了,这个页面就要显示他的用户信息,还可以发帖什么的。所以有个 before_filter 里的 find_user。
before_filter :find_user, :only => [:a,:b,:c,:d]
before_filter :check_permission, :only => [:c,:d]
不知道这样写符合你的业务逻辑不
#5 楼 @lin_style 用两个filter
会比较好:
before_filter find_user, :only => [:a, :b, :c, :d]
before_filter authenticate_user, :only => [:c, :d]
private
def find_user
@user = User.find_by_id(session[:user_id])
end
def authenticate_user
@user and redirect_to(:controller=>"welcome",:action => "index")
end
另外建议楼主下次提问时吧代码格式化一下,方便大家看。
终于懂楼主要干啥了。
以我以往的做法,套用@zzhattzzh 的代码
before_filter find_user
before_filter authenticate_user , :only => [:c, :d]
因为,偶页面的 head 一般都有放用户信息的,如果登陆就会展示出来,所以不做 only,嘿嘿。
#14 楼 @help5305fff #13 楼 @cxh116 #11 楼 @zzhattzzh 先谢谢大家。 如果两个 before_filter,是不是相当 before_filter 权限被弱化了?
比如以前这些 ACTION 只有登陆才能用,直接在 before_filter 里寻找 USER,如果没有就回首页,这样 before_filter 起到一个权限判断作用;
现在这些 ACTION 登陆和不登陆都可以做,那具体的权限只能到具体的 ACTION 函数里面判断。比如在 ACTION 里取到@user 信息做一些判断什么的。现在则要在 ACTION 里面判断是否有这个@user ,然后做对应的事情。
既然 before_filter 已经被弱化,为什么还要写两个 before_filter? 直接
def find_user
if !session[:user_id]
return
end
@user = User.find_by_id(session[:user_id])
if !@user
redirect_to(:controller=>"welcome",:action => "index")
end
end
然后在具体的 ACTION 函数里,判断
def common_event_content
#公共部分
@event_id = params[:id]
@event_contents = CommonEventContent.where(["event_id=?", @event_id]).order('id desc').page(params[:page]).per(10)
if !@user
return
end
#需要登陆部分
end
比较惯用的做法是一个 current_user 方法,一个 require_logined 方法,current_user 是调用的时候获取,不需要作为过滤器,require_logined 是过滤器,给需要登录的 action 加上。
实际在用的代码例子 https://github.com/chloerei/code_campo/blob/master/app/controllers/application_controller.rb
我现在做法是需要登陆的 都在 before_filter 加上,保证登陆 ACTION 里的@user变量是 OK 的。
主要修改在两个地方 (觉得这样改动最小了。。) 1)不需要登陆和登陆的函数里,代码整理成两部分,在做登陆逻辑前插个判断是否登陆,如果没有就直接返回了。 2)对应的 erb 文件里做一些调整显示
再次谢谢大家
#15 楼 @lin_style 看不懂你说的是什么意思。“现在这些 ACTION 登陆和不登陆都可以做,那具体的权限只能到具体的 ACTION 函数里面判断。比如在 ACTION 里取到@user 信息做一些判断什么的。现在则要在 ACTION 里面判断是否有这个@user ,然后做对应的事情。”里面“这些 action”指的是那些 action?为甚么用两个 filter 的话:"那具体的权限只能到具体的 ACTION 函数里面判断"?