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

Reply via email to