This project is archived and is in readonly mode.

before_filter return false doesn't detain running the action
Reported by Mage | September 17th, 2010 @ 01:51 AM
I am not sure that it is a bug in Rails 3 or not.
I just came back to Rails after a long break and I was refreshing my memory about before_filter.
In Rails book and Google results I read return false in before_filter should stop the chain and prevents action running.
class ClubsController < ApplicationController                                                                                                                                                                                                
  before_filter :test                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
  def index                                                                                                                                                                                                                                  
    logger.info ' --- *** index *** ---'                                                                                                                                                                                                     
    @clubs = Club.all                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
    respond_to do |format|                                                                                                                                                                                                                   
      format.html # index.html.erb                                                                                                                                                                                                           
      format.xml  { render :xml => @clubs }                                                                                                                                                                                                  
    end                                                                                                                                                                                                                                      
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                           
  protected                                                                                                                                                                                                                                  
  def test                                                                                                                                                                                                                                   
    logger.info '--- *** filter *** ---'                                                                                                                                                                                                     
    render text: 'text'                                                                                                                                                                                                                      
    return false                                                                                                                                                                                                                             
  end                                                                                                                                                                                                                                        
end
Log output for this:
Started GET "/clubs" for 127.0.0.1 at 2010-09-17 02:28:25 +0200
  Processing by ClubsController#index as HTML
--- *** filter *** ---
Rendered text template (0.0ms)
Completed 200 OK in 13ms (Views: 13.0ms | ActiveRecord: 0.0ms)
Which is fine.
Now I remove the render text: line from the filter method.
  protected
  def test
    logger.info '--- *** filter *** ---'
    #render text: 'text'
    return false
  end
The log putput will look like:
Started GET "/clubs" for 127.0.0.1 at 2010-09-17 02:27:23 +0200
  Processing by ClubsController#index as HTML
--- *** filter *** ---
 --- *** index *** ---
  Club Load (0.0ms)  SELECT "clubs".* FROM "clubs"
Rendered clubs/index.html.erb within layouts/application (3.0ms)
Completed 200 OK in 17ms (Views: 6.0ms | ActiveRecord: 0.0ms)
As you see 'return false' simply didn't stop the action. Is this a rails bug or a new feature in Rails 3?
I am using Gentoo, rvm, ruby 1.9.2, rails 3.0.0, development env.
    Mage
Comments and changes to this ticket
- 
         Rohit Arondekar September 17th, 2010 @ 03:20 AM- Importance changed from  to Low
 I don't see why it should stop the action from executing. If you don't want the action to execute you ought to redirect/render or raise an error. If you have more before filters then if one of them returns false, that should stop the filter chain iirc. Also I found this: http://m.onkey.org/2009/7/31/stop-returning-false Maybe it's an old feature that has been removed? 
- 
            
         Mage September 17th, 2010 @ 03:37 AMI have the lastest beta (8) version of Agile Web Development with Rails (4th edition) book which I think is quite official for Rails. On page 358 it says: "Filters can be passive, monitoring activity performed by a controller. They can also take a more active part in request handling. If a before filter returns false, processing of the filter chain terminates, and the action is not run. A filter may also render output or redirect requests, in which case the original action never gets invoked." Which is the same you can find on webpages. I am not sure wheter return false without any rendering is useful or not, but it seems this change is either not documented or not planned. before_filter also lacks documentation in API I also asked the authors of the book same time I sent this ticket. 
- 
         Rohit Arondekar September 17th, 2010 @ 06:02 AMChanged before_filter halting to happen automatically on render or redirect but no longer on simply returning false [David Heinemeier Hansson] http://github.com/rails/rails/raw/d8d8334a0be51e8c34876699d9101bf39... 
- 
         Rohit Arondekar September 17th, 2010 @ 09:55 AM- State changed from new to invalid
 
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>
 Jeremy Kemper
      Jeremy Kemper
 Mage
      Mage
 Rohit Arondekar
      Rohit Arondekar