This project is archived and is in readonly mode.

#5644 ✓invalid
Mage

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

    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

    Mage September 17th, 2010 @ 03:37 AM

    I 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

    Rohit Arondekar September 17th, 2010 @ 06:02 AM

    Changed 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

    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>

People watching this ticket

Pages