Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

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

#5673

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

Reported by Reinier de Lange · September 21st, 2010 @ 10:24 AM

State: resolved
Milestone: 3.0.6
Assigned to: Andrew White Andrew White
Importance: Low

Activity

  1. Rohit Arondekar
    Rohit Arondekar
    • 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.

    September 21st, 2010 @ 11:03 AM

  2. Reinier de Lange
    Reinier de Lange

    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).

    September 21st, 2010 @ 11:10 AM

  3. Rohit Arondekar
    Rohit Arondekar
    • 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!

    September 22nd, 2010 @ 10:47 AM

  4. Reinier de Lange
  5. David Trasbo
    David Trasbo

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

    September 25th, 2010 @ 06:13 PM

  6. Joey
    Joey

    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

    September 26th, 2010 @ 07:00 AM

  7. Joey
    Joey

    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
    

    September 26th, 2010 @ 07:06 AM

  8. Reinier de Lange
    Reinier de Lange

    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?

    September 26th, 2010 @ 09:11 AM

  9. Reinier de Lange
    Reinier de Lange

    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.

    September 26th, 2010 @ 03:50 PM

  10. Joey
    Joey

    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.

    September 28th, 2010 @ 04:07 AM

  11. Rohit Arondekar
    Rohit Arondekar
    • State changed from needs-more-info to invalid

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

    September 29th, 2010 @ 02:09 AM

  12. Ryan Bigg
    Ryan Bigg

    Automatic cleanup of spam.

    October 9th, 2010 @ 09:45 PM

  13. manuel
    manuel
    • 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.

    October 12th, 2010 @ 07:26 PM

  14. manuel
    manuel

    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
    

    October 12th, 2010 @ 07:38 PM

  15. manuel
    manuel

    ...

    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
    

    October 12th, 2010 @ 07:38 PM

  16. Reinier de Lange
    Reinier de Lange

    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.

    October 12th, 2010 @ 07:52 PM

  17. David Trasbo
    David Trasbo
    • State changed from invalid to open

    October 12th, 2010 @ 08:46 PM

  18. manuel
    manuel

    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? ;-)

    October 15th, 2010 @ 05:20 PM

  19. Reinier de Lange
    Reinier de Lange

    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
    

    October 15th, 2010 @ 07:09 PM

  20. Reinier de Lange
    Reinier de Lange

    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"
    

    October 15th, 2010 @ 07:12 PM

  21. manuel
    manuel

    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...

    October 17th, 2010 @ 03:13 PM

  22. manuel
    manuel

    really interesting format here btw ;-)

    October 17th, 2010 @ 03:14 PM

  23. Nathaniel Jones
    Nathaniel Jones

    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.

    October 30th, 2010 @ 02:01 AM

  24. Jeff Kreeftmeijer
    Jeff Kreeftmeijer
    • Tag cleared.

    Automatic cleanup of spam.

    November 1st, 2010 @ 05:01 PM

  25. Keith Tom
    Keith Tom

    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.

    November 9th, 2010 @ 02:10 AM

  26. Keith Tom
    Keith Tom

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

    November 10th, 2010 @ 04:39 PM

  27. Aleksey Zatvornitskiy
    Aleksey Zatvornitskiy

    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
    

    January 11th, 2011 @ 11:12 AM

  28. Reinier de Lange
    Reinier de Lange

    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.

    January 11th, 2011 @ 03:43 PM

  29. Peter Vandenberk
    Peter Vandenberk

    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

    January 24th, 2011 @ 12:40 PM

  30. Manfred Stienstra
    Manfred Stienstra

    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.

    February 25th, 2011 @ 10:48 AM

  31. Manfred Stienstra
    Manfred Stienstra

    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.

    February 25th, 2011 @ 11:39 AM

  32. James Adam
    James Adam

    I've seen exactly the same behaviour in Rails 3.0.4

    March 23rd, 2011 @ 04:50 PM

  33. James Adam
    James Adam

    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.

    March 23rd, 2011 @ 04:53 PM

  34. Andrew White
    Andrew White
    • Milestone set to 3.0.6
    • Assigned user set to Andrew White

    March 23rd, 2011 @ 06:06 PM

  35. Repository
    Repository
    • 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 [Rails3] Conditional before_filter not always executed for implicit resource ... state:resolved] https://github.com/rails/rails/commit/35de70fa2b91e1927686ad651de6f...

    March 23rd, 2011 @ 11:34 PM

  36. Repository
    Repository

    (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 [Rails3] Conditional before_filter not always executed for implicit resource ... state:resolved] https://github.com/rails/rails/commit/9772de8d459960cc114c5b214343b...

    March 23rd, 2011 @ 11:34 PM

  37. Andrew White
    Andrew White

    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.

    March 24th, 2011 @ 12:38 AM