1

我试图让 before_filter 处理需要用户登录的操作,但是一定有问题,因为它不是。

我使用一个名为“session_helper.rb”的帮助文件进行登录/注销以及检查用户是否已登录(已签名?)。如果在动作或视图中使用它可以正常工作,但是在将它与 before_filer 一起使用时它不起作用。如果我注销用户并尝试访问“/projects/new”,则可以这样做,但不应该这样做。

我究竟做错了什么?

项目负责人:

class ProjectsController < ApplicationController
  before_filter :signed_in?, :except => [:index]  // <-- doesn't prevent e.g. the action "new" to be executed

  def new
    @project = Project.new
    @users = (current_user.blank? ? User.all : User.find(:all, :conditions => ["id != ?", current_user.id]))
  end

  def index
    @projects = Project.all

    if signed_in?  // <-- works as it should
      @users_projects = Project.where(:user_id => current_user.id)
    end
  end

  ... other actions ...

end

session_helper.rb

module SessionsHelper

  def sign_in(user)
    cookies.permanent[:remember_token] = user.remember_token
    self.current_user = user
  end

  def signed_in?
    !current_user.nil?
  end

  def current_user=(user)
    @current_user = user
  end

  def current_user
    @current_user ||= User.find_by_remember_token(cookies[:remember_token])
  end

  def sign_out
    self.current_user = nil
    cookies.delete(:remember_token)
  end
end
4

2 回答 2

6

所以, before_filter 是一个有点误导的名字。它不是真正的过滤器。并不是说它会过滤掉其他动作并在您返回虚假值时阻止它们发生,并在您返回真实值时允许它们发生。这实际上是一种先调用方法的方法。可以将其视为“在调用路由触发的操作之前,调用以下方法”。

事实上,在 Rails 4 中,他们将 before_filter 重命名为 before_action,这应该会减轻前进的困惑。

你只是从 signed_in 中返回 T/F?所以它正在检查并继续前进,因为你没有告诉它根据检查的结果做任何特别的事情。

所以与其调用signed_in?像这样的东西会起作用:

before_filter :authorize, :except => [:index]

def authorize
  redirect_to login_url, alert: "Not authorized" if !signed_in?
end

跳,有帮助。

于 2013-02-11T19:33:36.820 回答
1

当没有当前登录时,我总是看到 before_filter 引发异常或重定向到另一个页面。我不确定返回 false 会阻止页面呈现。

于 2013-02-11T19:21:51.617 回答