lists-MTAS8qzKI1CBHsrSJzyHKA@public.gmane.org
2009-Mar-06 20:52 UTC
Filter defined in lib file required in environment.rb disappears from filter_chain in production environment. Why?
Hi all, I have initially posted this question to stack overflow but I think it''s specific enough that it warrants being posted here. I hope this is not bashed as crossposting. Here''s the original question: http://stackoverflow.com/questions/620146/rails-filter-defined-in-lib-file-required-in-environment-rb-disappears-from-filt It''s up to you whether you want to answer here or there, I''ll make sure that the final solution is posted to both places. So here''s the question text reproduced: In my rails application, I have a file in lib that, among other things, sets up a filter that runs on all controllers. When running under development environment, everything runs fine. However, under production the filter goes missing. Funny thing is, by inspecting the `filter_chain`, I noticed other filters remain, eg. those defined in plugins, or later in the specific controller class. I''ve tested this with both rails edge and v2.3.0. I''ve isolated the behavior to the following tiny test case: # app/controllers/foo_controller.rb class FooController < ApplicationController def index render :text => ''not filtered'' end end # lib/foobar.rb ActionController::Base.class_eval do before_filter :foobar def foobar render :text => ''hi from foobar filter'' end end # config/environment.rb (at end of file) require ''foobar'' --- Here''s the output I get when running under the **development** environment: $ script/server & $ curl localhost:3000/foo > hi from foobar filter And here''s the output for the **production** environment: $ script/server -e production & $ curl localhost:3000/foo > not filtered --- As alluded to before, it works fine for any environment when I do the same thing via plugin. All I need is to put what''s under `lib/ foobar.rb` in the plugin''s `init.rb` file. So in a way I already have a workaround, but I''d like to understand what''s going on and what''s causing the filter to go missing when in production. I conjecture it''s something in the different ways Rails handles loading in the different environments, but I need to dig deeper. ### update Indeed, I''ve now narrowed it down to the following config line: config.cache_classes = false If, in `production.rb`, `config.cache_classes` is changed from `true` to `false`, the test application works properly. I still wonder why class reloading is causing such thing. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung
2009-Mar-06 21:20 UTC
Re: Filter defined in lib file required in environment.rb disappears from filter_chain in production environment. Why?
On Mar 6, 8:52 pm, li...-MTAS8qzKI1CBHsrSJzyHKA@public.gmane.org wrote:> > Indeed, I''ve now narrowed it down to the following config line: > > config.cache_classes = false > > If, in `production.rb`, `config.cache_classes` is changed from `true` > to `false`, the test application works properly. > > I still wonder why class reloading is causing such thing.Because cache_classes does a little more than just that. The way before filters work, if Foo < Bar then only those filters defined in Bar at that point will be inherited by Foo - adding them to Bar at a later date will not do anythingn In development mode, the app starts, your file is required, the filter added to ActionController::Base. Later the first request comes along, the controller is loaded and it inherits that filter. When cache_classes is true then all of your application classes are loaded ahead of time. This happens before your file is required, so all of your controllers already exist when that file is run and so it has no effect. You could solve this by requiring this file from an initializer (ensuring it runs before app classes are loaded), but really why wouldn;t you just put this in application.rb ? Fred --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
lists-MTAS8qzKI1CBHsrSJzyHKA@public.gmane.org
2009-Mar-06 21:54 UTC
Re: Filter defined in lib file required in environment.rb disappears from filter_chain in production environment. Why?
Hi, thanks for the detailed answer, I thought in production files were still loaded on-demand, just never reloaded. (I guess that''s how it was aeons ago). On Mar 6, 6:20 pm, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> has no effect. You could solve this by requiring this file from an > initializer (ensuring it runs before app classes are loaded), butIn my minimal test case, yes that did it. In my actual application the code in the lib file depended on libraries that were being required later in the environment, so I had to do a bit more of moving code around, but it seems to have worked.> really why wouldn;t you just put this in application.rb ?Oh that''s a long story… bottomline is that it''s a file that may be shared among many applications. But really, then the question is, why not make it a plugin, and well, maybe I should do it, but I was still curious about what in the loading process was causing the code to break, since I knew it worked in older rails apps I had. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung
2009-Mar-06 22:50 UTC
Re: Filter defined in lib file required in environment.rb disappears from filter_chain in production environment. Why?
On Mar 6, 9:54 pm, li...-MTAS8qzKI1CBHsrSJzyHKA@public.gmane.org wrote:> Hi, thanks for the detailed answer, I thought in production files were > still loaded on-demand, just never reloaded. (I guess that''s how it > was aeons ago). >That changed in 2.2. The change is mainly needed for thread safeness, since require is fundamentally thread dangerous in ruby so you need to get all of that out of the way at app startup. Fred> On Mar 6, 6:20 pm, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > wrote: > > > has no effect. You could solve this by requiring this file from an > > initializer (ensuring it runs before app classes are loaded), but > > In my minimal test case, yes that did it. In my actual application the > code in the lib file depended on libraries that were being required > later in the environment, so I had to do a bit more of moving code > around, but it seems to have worked. > > > really why wouldn;t you just put this in application.rb ? > > Oh that''s a long story… bottomline is that it''s a file that may be > shared among many applications. > > But really, then the question is, why not make it a plugin, and well, > maybe I should do it, but I was still curious about what in the > loading process was causing the code to break, since I knew it worked > in older rails apps I had.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung
2009-Mar-06 22:52 UTC
Re: Filter defined in lib file required in environment.rb disappears from filter_chain in production environment. Why?
On Mar 6, 9:54 pm, li...-MTAS8qzKI1CBHsrSJzyHKA@public.gmane.org wrote:> > > has no effect. You could solve this by requiring this file from an > > initializer (ensuring it runs before app classes are loaded), but > > In my minimal test case, yes that did it. In my actual application the > code in the lib file depended on libraries that were being required > later in the environment, so I had to do a bit more of moving code > around, but it seems to have worked.In general you don''t want to be doing anything at the bottom of environment.rb because of this whole loading models/controllers ahead of time (eg if you required a gem that a model needs when it is loaded then your app will die on startup in production mode). Fred --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
lists-MTAS8qzKI1CBHsrSJzyHKA@public.gmane.org
2009-Mar-07 02:24 UTC
Re: Filter defined in lib file required in environment.rb disappears from filter_chain in production environment. Why?
> In general you don''t want to be doing anything at the bottom of > environment.rb because of this whole loading models/controllers ahead > of time (eg if you required a gem that a model needs when it is loaded > then your app will die on startup in production mode).Yeah. My real case was way more involved, and this is the way I found to work solve the issue: config.after_initialize do require ''foobar'' end The `after_initialize` runs after the framework has been initialized but before it loads the application files, hence, it''ll affect ActionPack::Base after it''s been loaded, but before the application controllers are. I guess that''s the safe way to deal with all the preloading that goes on. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---