Jean-Christophe Michel wrote:
Hi all,
My problem is to try to call a method once per page request.
(Context: I want to detect the current lang for localization, and this
has to be done on each request, so lang passed through uri can have
priority over session, browser prefs or default app lang).
The way I followed is to have an independant class, Locale, which method
init is called through an ApplicationController before_filter.
Fine.
But when I use a render_component in my layout, to render a menu for
instance, a second controller is called, and the negociation for the
lang is done once more. To avoid this, I'd like to be sure this method
is called only once (it wastes ressources, and more, I need to be sure
that the lang is consistent through my components on the same page).
Rick Bradley suggested :
Seems like a before_filter should be sufficient, simply
def my_method
return true if @@my_method_called
@@my_method_called = true
# do something
end
Rick, your solution is not working, at least here with scgi+apache2 in
dev mode. The class vars are not reinited on each request, so once
my_method was called, it's not run any more until the server is
restarted. In my case this mean you cannot change the lang :p
I just tried with webrick and get the same result.
That's why I concluded that there should be a hook to call some methods
once per page request. Digging in core code, I think it could be around
Dispatcher#prepare_application
in trunk/railties/lib/dispatcher.rb
Opinions ?
I suggest to place language information on the request object. Add an
attr_accessor to class AbstractRequest
class ActionController::AbstractRequest
attr_accessor :language
end
and set this in your controller
class ApplicationController < ActionController::Base
def language
request.language ||= your_expensive_language_computation
end
helper_method :language
end
Another option would be to install a filter that sets language on the
request object and store it in @language on the controller for direct
access. From there it will be propagated to your views automatically.
class ApplicationController < ActionController::Base
before_filter :set_language
private
def set_language
@language = (request.language ||=
your_expensive_language_computation)
end
end
and use @language directly (similar to the method described in
http://railsexpress.de/blog/articles/2005/11/18/components-may-not-be-evil-but-they-sure-can-be-slow)
-- stefan
--
For rails performance tuning, see: http://railsexpress.de/blog
Subscription: http://railsexpress.de/blog/xml/rss20/feed.xml
_______________________________________________
Rails-core mailing list
Rails-core@lists.rubyonrails.org
http://lists.rubyonrails.org/mailman/listinfo/rails-core