我正在尝试从一个特定页面 - 登录页面中排除控制器的操作。我希望代码在每个其他页面上执行。
在我的控制器中,我有:
def user_check
@current_user ||= User.find(session[:user_id]) if session[:user_id]
if (session[:user_id])
@loginstatus = "You are logged in as: #{@current_user.name}"
elseif current_page?('/signin') == true
@loginstatus = "Please login to use this application"
else
redirect_to '/sessions/new', :error => "You are not logged in"
end
end
给我带来麻烦的是
elseif current_page?('/signin') == true
我在application.html.erb中用
调用它<%= user_check %>
当我这样做时,我得到了
pp / views / layouts / application.html.erb第94行引出: 未定义的方法`current_page?'为# Rails.root:C:/ Users / cmendla / RubymineProjects / Rl2
但是 - 如果我将以下内容放在XX.html.erb页面中,它可以正常工作。
<%= render(:partial => 'shared/alt_nav') if current_page?('/help') %>
我不明白为什么current_page?检查在页面上有效,但在def中的elseif
内无效。
答案 0 :(得分:2)
您的代码效率不高 - 您正在验证两个完全(不相关)的条件集 - 是否声明了变量以及用户是否正在访问页面。
我会做以下事情:
#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_filter :check_user
private
def check_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
if (session[:user_id])
@loginstatus = "You are logged in as: #{@current_user.name}"
else
redirect_to '/sessions/new', :error => "You are not logged in"
end
end
end
#app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
skip_before_filter :check_user
end
这有两件事:
1)它围绕一个条件构建条件逻辑。
2)它使你的逻辑动作定向
你遇到的主要问题是在条件逻辑中调用current_page?
基本上与你的应用程序的任何其他部分紧密相关。 Rails应用程序是object orientated,并且应该表现得如此。
当您验证用户是否访问过页面时,您忽略了以下事实:在您的开发中,“页面”可以表示/意味着完全不同的东西。更不用说您可能希望将您的功能扩展到该页面以外(“注册”等等?)。
这意味着当您按原样调用条件逻辑时,最好保持基本级别简单(是否已登录?),并根据操作<进行过滤/ em>用户正在执行。
例如......
#app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
skip_before_filter :check_user, except: :destroy #-> doesn't check user login for user login / registration; does for logout
end
希望这有帮助。
答案 1 :(得分:0)
将登录页面移动到另一个控制器(另一个视图子目录),也改变路径。那将是最干净的。
如果您希望所有安全页面都调用user_check,最简单的方法是将您的登录安装到/ unsecure / signon路由,映射到&unsecure_controller.rb&#39;没有调用user_check。