This project is archived and is in readonly mode.

#5673 ✓resolved
Reinier de Lange

[Rails3] Conditional before_filter not always executed for implicit resource actions

Reported by Reinier de Lange | September 21st, 2010 @ 10:24 AM | in 3.0.6

As an example, consider the following fragment found in refinerycms-news:

class NewsItemsController < ApplicationController

  before_filter :find_news_item, :only => [:show]

protected

  def find_news_item
    @news_item = NewsItem.published.find(params[:id])
  end

end

I found out that find_news_item is not always executed when the show method is not explicitly defined (only a show view is present). As this might be dependent on the system configuration, I'm listing the important parts of mine below:

  • ruby 1.8.7 (2010-04-19 patchlevel 253) [x86_64-linux], MBARI 0x6770, Ruby Enterprise Edition 2010.02

packaged using Bundler 1.0.0:

  • rails 3.0.0
  • rack 1.2.1

Comments and changes to this ticket

  • Rohit Arondekar

    Rohit Arondekar September 21st, 2010 @ 11:03 AM

    • Importance changed from “” to “Low”

    Could not reproduce this issue.

    First, versions:

    • Ruby — ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]
    • Rails — 3.0.0
    • Rack — rack-1.2.1

    These are the steps I followed:

    • Create new app
    • Create Pages controller with index & show actions.
    • pages_controller.rb:
    class PagesController < ApplicationController
    
      before_filter :add_message, :only => [:show]
    
      def index
      end
    
      private
      def add_message
        @message = "Hello from add_message()"
      end
    end
    
    • show.html.erb:
    <%= @message if @message%>
    

    Run the server and navigate to localhost:3000/pages/show — the message was shown.

    Could there be something else that caused the issue? Also can somebody please try it on Ruby 1.8.7 and REE.

  • Reinier de Lange

    Reinier de Lange September 21st, 2010 @ 11:10 AM

    It must be noted that this specifically wasn't working for the production environment, I couldn't reproduce this error either in development mode on my machine (ruby 1.8.7 (2010-04-19 patchlevel 253) [i686-darwin10.4.0], MBARI 0x6770, Ruby Enterprise Edition 2010.02).

  • Rohit Arondekar

    Rohit Arondekar September 22nd, 2010 @ 10:47 AM

    • State changed from “new” to “needs-more-info”

    Can you please try debugging this on your production server to find out if it's a Rails issue or not? Or maybe try and reproduce the production server environment and see if you can reproduce the issue. Thanks!

  • Reinier de Lange
  • David Trasbo

    David Trasbo September 25th, 2010 @ 06:13 PM

    I'd suggest doing a grep or an ack for skip_before_filter. Just the first thing that came to my mind.

  • Joey

    Joey September 26th, 2010 @ 07:00 AM

    I am experiencing the same issue where the before_filter is not always being executed. This is occurring in my dev environment. I thought I was going crazy.
    I am using

    Ruby 1.9.2 P0 (Windows 7 x64)
    Rails 3.0.0

  • Joey

    Joey September 26th, 2010 @ 07:06 AM

    I use the following

    class ApplicationController < ActionController::Base
    before_filter :set_path_info
    
      def set_path_info
        session['Path Info'] = request.path_info
      end
    end
    
  • Reinier de Lange

    Reinier de Lange September 26th, 2010 @ 09:11 AM

    That's really strange, as that is just the usual construct. I'll try to reproduce the bug today and find out what's going wrong. @Joey, what app server are you using on your dev machine? Mongrel?

  • Reinier de Lange

    Reinier de Lange September 26th, 2010 @ 03:50 PM

    So far no clue as I can't reproduce the bug locally (production env). The only difference is that the deployment server is running passenger while I'm using webrick, so it might be a passenger bug. If Joey doesn't find anything either, it's fine with me to mark this ticket invalid.

  • Joey

    Joey September 28th, 2010 @ 04:07 AM

    I am using WEBrick 1.3.1. . I am not able to reproduce the error today after I restarted my machine. If I get the error again, I will try to better document the steps to reproduce it.

  • Rohit Arondekar

    Rohit Arondekar September 29th, 2010 @ 02:09 AM

    • State changed from “needs-more-info” to “invalid”

    Closing ticket for now. Just leave a comment if you need it to be re-opened.

  • Ryan Bigg

    Ryan Bigg October 9th, 2010 @ 09:45 PM

    Automatic cleanup of spam.

  • manuel

    manuel October 12th, 2010 @ 07:26 PM

    • Tag set to passenger filter

    Hi,

    i can confirm this bug - but i think it is a passenger problem. i'm using passenger - first with latest stable and then with 3 rc. with webrick and mongrel this problem doesn't exist.

    i have the following code in one of my controllers:

    before_filter :load_organizer def load_organizer

    @organizer = Organizer.find_by_code(session[:contr])
    

    end

    before_filter :load_event #, :only => [:details, :reservation, :places] def load_event

    @event = @organizer.events.find(params['id']) if params['id']
    

    end

    before_filter :load_rank #, :only => [:places] def load_rank

    @rank = @event.hall.ranks.find(params['rank']) if params['rank']
    

    end

    with the conditions it sometimes worked but the most time it didnt - so i commented out the conditions and added the ifs to execute the lines only if the right parameters are given.

  • manuel

    manuel October 12th, 2010 @ 07:38 PM

    ps: sorry for the bad formatting - here my workaround for passenger again:

    before_filter :load_organizer def load_organizer
      @organizer = Organizer.find_by_code(session[:contr])
    end
    
    before_filter :load_event #, :only => [:details, :reservation, :places] def load_event
      @event = @organizer.events.find(params['id']) if params['id']
    end
    
    before_filter :load_rank #, :only => [:places] def load_rank
      @rank = @event.hall.ranks.find(params['rank']) if params['rank']
    end
    
  • manuel

    manuel October 12th, 2010 @ 07:38 PM

    ...

    before_filter :load_organizer
    def load_organizer
      @organizer = Organizer.find_by_code(session[:contr])
    end
    
    before_filter :load_event #, :only => [:details, :reservation, :places]
    def load_event
      @event = @organizer.events.find(params['id']) if params['id']
    end
    
    before_filter :load_rank #, :only => [:places]
    def load_rank
      @rank = @event.hall.ranks.find(params['rank']) if params['rank']
    end
    
  • Reinier de Lange

    Reinier de Lange October 12th, 2010 @ 07:52 PM

    I managed to reproduce this problem in a rails application with a cucumber test (capybara). As this is closed source, I'm currently stripping it down to something I can upload to github. Hopefully it will help us find out what's causing this.

  • David Trasbo

    David Trasbo October 12th, 2010 @ 08:46 PM

    • State changed from “invalid” to “open”
  • manuel

    manuel October 15th, 2010 @ 05:20 PM

    does this really interest nobody? where do you all host your rails apps? still on mongrel clusters with a proxy???? or does nobody really use rails for production sites? ;-)

  • Reinier de Lange

    Reinier de Lange October 15th, 2010 @ 07:09 PM

    I uploaded the application with the failing cucumber feature to github: http://github.com/moiristo/before_filter_bug.

    It does not reproduce the exact same issue described in this ticket, as the application shows that before_filters are called while they should not be called. However, I do think that both issues are closely related.

    Please try to run the cucumber feature and let me know if you're experiencing the same problem. Here is the output I get:

    
    $ cucumber features
    Using the default profile...
    WARNING: No DRb server is running. Running features locally:
    ......"find_account_detail before_filter called for action: edit. Allowed actions: [:edit, :update, :delete, :destroy]."
    .."find_account_detail before_filter called for action: update. Allowed actions: [:edit, :update, :delete, :destroy]."
    ......"[!BUG!] find_account_detail before_filter called for action: new. Allowed actions: [:edit, :update, :delete, :destroy]."
    F------..."[!BUG!] find_account_detail before_filter called for action: new. Allowed actions: [:edit, :update, :delete, :destroy]."
    F------..."[!BUG!] find_account_detail before_filter called for action: new. Allowed actions: [:edit, :update, :delete, :destroy]."
    F------...."find_account_detail before_filter called for action: edit. Allowed actions: [:edit, :update, :delete, :destroy]."
    .."find_account_detail before_filter called for action: update. Allowed actions: [:edit, :update, :delete, :destroy]."
    ...
    
    (::) failed steps (::)
    
    Couldn't find AccountDetail without an ID (ActiveRecord::RecordNotFound)
    ./app/controllers/account_details_controller.rb:58:in `find_account_detail'
    ./features/step_definitions/web_steps.rb:35
    ./features/step_definitions/web_steps.rb:14:in `with_scope'
    ./features/step_definitions/web_steps.rb:34:in `/^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/'
    features/account_management.feature:24:in `And I follow "Telefoonnummer toevoegen"'
    
    Couldn't find AccountDetail without an ID (ActiveRecord::RecordNotFound)
    ./app/controllers/account_details_controller.rb:58:in `find_account_detail'
    ./features/step_definitions/web_steps.rb:35
    ./features/step_definitions/web_steps.rb:14:in `with_scope'
    ./features/step_definitions/web_steps.rb:34:in `/^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/'
    features/account_management.feature:34:in `And I follow "E-mail adres toevoegen"'
    
    Couldn't find AccountDetail without an ID (ActiveRecord::RecordNotFound)
    ./app/controllers/account_details_controller.rb:58:in `find_account_detail'
    ./features/step_definitions/web_steps.rb:35
    ./features/step_definitions/web_steps.rb:14:in `with_scope'
    ./features/step_definitions/web_steps.rb:34:in `/^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/'
    features/account_management.feature:44:in `And I follow "Website toevoegen"'
    
    Failing Scenarios:
    cucumber features/account_management.feature:22 # Scenario: Creating phone numbers
    cucumber features/account_management.feature:32 # Scenario: Creating email addresses
    cucumber features/account_management.feature:42 # Scenario: Creating websites
    
    5 scenarios (3 failed, 2 passed)
    48 steps (3 failed, 18 skipped, 27 passed)
    0m2.769s
    
  • Reinier de Lange

    Reinier de Lange October 15th, 2010 @ 07:12 PM

    Again, here is my setup if it's important:

      system:
        uname:       "Darwin Marvin.local 10.4.0 Darwin Kernel Version 10.4.0: Fri Apr 23 18:28:53 PDT 2010; root:xnu-1504.7.4~1/RELEASE_I386 i386"
        bash:        "/bin/bash => GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin10.0)"
        zsh:         "/bin/zsh => zsh 4.3.9 (i386-apple-darwin10.0)"
    
      rvm:
        version:      "rvm 1.0.6 by Wayne E. Seguin (wayneeseguin@gmail.com) [http://rvm.beginrescueend.com/]"
    
      ruby:
        interpreter:  "ruby"
        version:      "1.8.7"
        date:         "2010-04-19"
        platform:     "i686-darwin10.4.0"
        patchlevel:   "2010-04-19 patchlevel 253"
        full_version: "ruby 1.8.7 (2010-04-19 patchlevel 253) [i686-darwin10.4.0], MBARI 0x6770, Ruby Enterprise Edition 2010.02"
    
  • manuel

    manuel October 17th, 2010 @ 03:13 PM

    the same in 3.0.1 with all gems up2date

    in the controller:

      before_filter :load_event, :only => [:details, :reservation, :places]
      def load_event

    @event = @organizer.events.find(params['id'])
    
    
    
    
    end

    and the error (had to replace some parts with ****):

    Started GET "/****/places?rank=2&id=1" for ****** at Sun Oct 17 16:04:04 +0200 2010
      Processing by ******#places as HTML
      Parameters: {"id"=>"1", "rank"=>"2"}
    Rendered places/_places.html.erb (122.5ms)
    Rendered ****/places.html.erb within layouts/***** (124.7ms)
    Completed   in 129ms
    
    ActionView::Template::Error (undefined method `name' for nil:NilClass):
        1: <div id="places">
        2:   <h2>Platzwahl<span> | <%=h @event.name %> | <%=h @rank.name %></span></h2>
    ...
    

    so the event isn't executed.

    with the following ugly version its working:

      before_filter :load_event
        @event = @organizer.events.find(params['id']) if params['id']
      end
    

    this only happens deployed on passenger with tested versions: last stable, 3.0 pre-release. i hope someone can fix this asap, because that's a really ugly bug if you want to deploy your app, that was all fine in mongrel, and doesn't work at all in passenger...

  • manuel

    manuel October 17th, 2010 @ 03:14 PM

    really interesting format here btw ;-)

  • Nathaniel Jones

    Nathaniel Jones October 30th, 2010 @ 02:01 AM

    I have duplicated this bug in Rails 3.0.1:

    • Webrick 1.3.1 on ruby 1.9.2 (2010-08-18) [i386-darwin9.8.0]
    • Heroku stack bamboo-mri-1.9.2
    • config.cache_classes must be TRUE. This issue comes up in both development and production, but only if classes are cached.

    And the other way around, if I set my Heroku environment to development, the issue goes away. So class caching has something to do with it.

    A simple def show; end also cures the problem. Only implicit actions misbehave.

  • Jeff Kreeftmeijer

    Jeff Kreeftmeijer November 1st, 2010 @ 05:01 PM

    • Tag cleared.

    Automatic cleanup of spam.

  • Keith Tom

    Keith Tom November 9th, 2010 @ 02:10 AM

    Just wanted to confirm that I experienced both bugs mentioned in this thread:
    1) before_filter does not always execute
    2) before_filters executed despite restrictions

    Some of my setup:
    Rails 3.0.1
    WEBrick 1.3.1
    Ruby Enterprise Edition 1.8.7 2010.02
    Both locally and on Heroku Bamboo REE 1.8.7

    Only discovered this in production, however turning off class caching seems to solve both problems.

    With class caching on, explicitly defining the action seems to solve the first problem of having the before filter execute; however, I still had filters that were executing despite conditional options restricting that. Furthermore, I found the latter problem happened intermittently.

  • Keith Tom

    Keith Tom November 10th, 2010 @ 04:39 PM

    I'd like to correct myself: it seems explicitly defining the actions seems to solve both problems.

  • Aleksey Zatvornitskiy

    Aleksey Zatvornitskiy January 11th, 2011 @ 11:12 AM

    I have duplicated this bug in Rails 3.0.3 with ruby 1.9.2 and unicorn 1.1.4 (and 3.1.0) ONLY for PRODUCTION environment

    before_filter performed for actions without real definition.

    Without action method definition rails throws exception. My current fix for this problem!

    class Mobile::CampaignsController < ApplicationController
    
      before_filter :load_mobile_camapign, :except => [ :index, :new, :create, :ids_with_images ]
      
      # Fix unknown rails issue
      # A ActiveRecord::RecordNotFound occurred in campaigns#new:
      # Couldn't find Campaign without an ID
      # activerecord (3.0.3) lib/active_record/relation/finder_methods.rb:279:in `find_with_ids'
      def new; end
    
    
      private
      
      def load_mobile_camapign
        @campaign = current_account.mobile_campaigns.find params[:id]
      end
    
    end
    

    Yet another controller

    class Admin::UsersController < Admin::BaseController
      
      before_filter :load_account_user, :except => [ :index, :new, :create ]
      
      respond_to :html
    
      # A ActiveRecord::RecordNotFound occurred in users#new:
      # Couldn't find User without an ID
      # activerecord (3.0.3) lib/active_record/relation/finder_methods.rb:279:in `find_with_ids'
      def new; end
    
    
      private
    
      def load_account_user
        @user = @account.users.find params[:id]
      end
    
    end
    
  • Reinier de Lange

    Reinier de Lange January 11th, 2011 @ 03:43 PM

    Should this ticket still have low priority? IMO, the bug has been confirmed and I think it is not a minor bug. I understand a patch would be nice, but I have not been able to pinpoint what causes this issue.

  • Peter Vandenberk

    Peter Vandenberk January 24th, 2011 @ 12:40 PM

    FWIW, we are experiencing exactly the same issue... our setup is as follows:

    • rails 3.0.3
    • passenger 3.0.0
    • ruby 1.8.7 (2010-08-16 patchlevel 302) [x86_64-linux]

    As noted above, in our case this is a intermittent issue as well, and cannot be easily reproduced.

    Reinier de Lange wrote:

    It must be noted that this specifically wasn't working for the production environment, I couldn't reproduce this error either in development mode on my machine

    Same here...

    Reinier de Lange wrote:

    Should this ticket still have low priority? IMO, the bug has been confirmed and I think it is not a minor bug.

    +1, especially as the workarounds are butt-ugly :P

  • Manfred Stienstra

    Manfred Stienstra February 25th, 2011 @ 10:48 AM

    For me the filters run just fine on development (with both :except and :only). However in tests the filters is always run regardless of the options.

  • Manfred Stienstra

    Manfred Stienstra February 25th, 2011 @ 11:39 AM

    Here's a patch with a failing test for the problem described above. I assume the problem has something to do with the "action_name == 'action'" filter in the callback and action_name not being set for implicitly defined actions.

    Workaround; the solution appears to be to define an empty method for now.

  • James Adam

    James Adam March 23rd, 2011 @ 04:50 PM

    I've seen exactly the same behaviour in Rails 3.0.4

  • James Adam

    James Adam March 23rd, 2011 @ 04:53 PM

    I should add that in my case, a filter (which was defined as :only occurring for some set of actions) was being fired for an implicit resource action that was not in that set.

  • Andrew White

    Andrew White March 23rd, 2011 @ 06:06 PM

    • Milestone set to 3.0.6
    • Assigned user set to “Andrew White”
  • Repository

    Repository March 23rd, 2011 @ 11:34 PM

    • State changed from “open” to “resolved”

    (from [35de70fa2b91e1927686ad651de6f8c3126929e9]) Fix filter :only and :except with implicit actions

    The method_name argument is "default_render" for implicit actions
    so use the action_name attribute to determine which callbacks to run.

    [#5673 state:resolved] https://github.com/rails/rails/commit/35de70fa2b91e1927686ad651de6f...

  • Repository

    Repository March 23rd, 2011 @ 11:34 PM

    (from [9772de8d459960cc114c5b214343b7ce08fea21c]) Fix filter :only and :except with implicit actions

    The method_name argument is "default_render" for implicit actions
    so use the action_name attribute to determine which callbacks to run.

    [#5673 state:resolved] https://github.com/rails/rails/commit/9772de8d459960cc114c5b214343b...

  • Andrew White

    Andrew White March 24th, 2011 @ 12:38 AM

    The reason it was working in development is the class reloading results in the filter chain being rebuilt on every request. It was also dependent on the order of requests to the controller whether the filter would run or not.

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>

Attachments

Referenced by

Pages