This project is archived and is in readonly mode.

#5644 ✓invalid

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                                                                                                                                                                                                                              ' --- *** index *** ---'                                                                                                                                                                                                     
    @clubs = Club.all                                                                                                                                                                                                                        
    respond_to do |format|                                                                                                                                                                                                                   
      format.html # index.html.erb                                                                                                                                                                                                           
      format.xml  { render :xml => @clubs }                                                                                                                                                                                                  
  def test                                                                                                                                                                                                                               '--- *** filter *** ---'                                                                                                                                                                                                     
    render text: 'text'                                                                                                                                                                                                                      
    return false                                                                                                                                                                                                                             

Log output for this:

Started GET "/clubs" for 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.

  def test '--- *** filter *** ---'
    #render text: 'text'
    return false

The log putput will look like:

Started GET "/clubs" for 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.


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:

    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]

  • 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=""></a>

People watching this ticket