before_filter, похоже, не "пинается"

Я пытаюсь заставить before_filter работать над действиями, требующими входа пользователя, однако что-то должно быть не так, потому что это не так.

Я использую вспомогательный файл с именем 'session_helper.rb' для входа в систему / выхода из системы, а также для проверки, вошел ли пользователь в систему (signature_in?). Это прекрасно работает, если используется внутри действия или в представлении, однако при использовании его с 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

sessions_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

2 ответа

Решение

Итак, before_filter - немного вводящее в заблуждение имя. Это не совсем фильтр. Дело не в том, что он отфильтрует другие действия и предотвратит их выполнение, если вы вернете ложное значение, и разрешит их, если вы вернете истинное. Это действительно способ вызова метода раньше всего. Думайте об этом как о "перед вызовом действия, вызванного маршрутом, вызовите следующий метод".

Действительно, в Rails 4 они переименовывают before_filter в before_action, и это должно смягчить путаницу в будущем.

Вы только что вернули T/F из Sign_in? Таким образом, он проверяет это и движется дальше, поскольку вы не сказали ему делать что-то особенное на основании результатов этой проверки.

Таким образом, вместо того, чтобы звонить подписано? Примерно так будет работать:

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

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

Хмель, который помогает.

Я всегда видел, как before_filter вызывал исключение или перенаправлял на другую страницу, когда нет текущего логина. Я не уверен, что возвращение false будет препятствовать отображению страницы.

Другие вопросы по тегам