문제

I'm trying to get before_filter to work on the actions that requires the user to be logged in, however something must be wrong because it's not.

I use a helper file called 'session_helper.rb' for login/logout as well as for checking if the user is logged in (signed_in?). That works fine if used inside an action or in the view, however while using it with the before_filer it's not working. If I log out the user and try to access '/projects/new' it's possible to do that, while it shouldn't be.

What am I doing wrong?

project controller:

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
도움이 되었습니까?

해결책

So, before_filter is a slightly misleading name. It is not really a filter. It isn't that it'll filter out the other actions and prevent them occurring if you return a falsey value, and allow them if you return a truthy one. It's really a way of calling a method before anything else. Think of it as 'before calling the action that the route has triggered, call the following method'.

Indeed, in Rails 4 they are renaming before_filter to before_action and that should alleviate the confusion moving forward.

You're just returning T/F from signed_in? So it's checking that and moving on, as you haven't told it to do anything special based on the results of that check.

So rather than calling signed_in? Something like this would work:

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

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

Hop that helps.

다른 팁

I've always seen the before_filter raise an exception or redirect to another page when there is no current login. I am not sure that returning false will prevent the page from rendering.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top