Preloading Globalize view translations in production

When you've properly extracted and translated view translations from your source code, here's a snippet to preload them all before the first request served in Production.

Dispatcher.to_prepare :globalize_view_translations do
  if RAILS_ENV == 'production' 
    translator = Globalize::DbViewTranslator.instance
      #Or whichever other means used to keep track of app specific supported languages 
      SupportedLanguage.find(:all).each do |lang|
        ViewTranslation.find(:all, :conditions => ['globalize_translations.language_id = ?', lang.language_id]).each do |tr|
          translator.send(:cache_add, tr.tr_key, tr.language, tr.pluralization_index, tr.text)
        end  
    end  
  end  
end

Dispatcher.to_prepare

An addition to 1.2 and Edge for quite some time.This callback is referenced

  • before the first request in Production
  • before each request in Development

Most notably initializes Observer instances

Posted on December 27th | 121 comments | Filed Under: GlobalizeRailsRuby | read on

Globalize::DbTranslate with :include and no base language patch

Globalize DB translations currently doesn't support a :select find option, which breaks hasmany :trough => atranslateable_model associations.

I've refactored the Globalize::DbTranslate module to an AR::Associations pattern, override Model.find to always preload translations whilst removing all of the custom finder SQL.

Benefits

  • Supports all of the ActiveRecord::Base#find functionality
  • Plugs in with existing globalize table structures (no migrations required)
  • There is no Base Locale.Edit or create in any language, any other language always retrieves a valid facet, albeit not always in the active Locale.
  • Retrieves all facet translations for a given model at once, thus Locale switching doesn't incur a database roundtrip overhead.

Caveats

I removed a tiny bit of functionality to allow me to focus on a initial prototype.

  • Bidi strings temp. removed
  • Removed piggy backing find option
  • Works best with only one Locale per request, which is fine in most situations.
  • The no Base Locale setup might not be ideal for all use cases.
  • Only tested with Edge (production, test and development envs)
  • Globalize unit test helper chokes with the Dependencies mechanism and I couldn't yet get the unit tests to run.

The rundown

AR association and Translateable.find

Setup an association in the translates() hook:

          has_many :translations, :class_name => 'Globalize::ModelTranslation', :conditions => ['globalize_translations.table_name = ?', table_name], :foreign_key => 'item_id'  

Override Translateable.find, scoped to always prefetch translations:

   alias_method :old_find, :find
   def find(*args)
      options = args.last.is_a?(Hash) ? args.last : {}
      if (options.has_key?(:untranslated) && options[:untranslated] == true)
          old_find(*args)
      else
         with_scope( :find => { :include => :translations }) do
            old_find(*args)
         end
       end  
    end    

Cherry pick facet content

     def find_translation_for_facet( facet )
         translations ||= []
         #highest priority, find for current language
         translations << self.translations.detect{|tr| tr.facet == facet.to_s && tr.language_id == Locale.language.id }
         #do we have a non-blank attribute in the model table?
         translations << read_attribute(facet)
         #find the first translation, for any language
         translations << self.translations.detect{|tr| tr.facet == facet.to_s && !tr.text.nil? }

         #we don't want nil or empty string
         translations.reject!(&:blank?)
         translations.empty? ? nil : (translations.first.respond_to?(:text) ? translations.first.text : translations.first)                          
      end  

The patch

Grab this patch and give it a whirl.

Feedback on this? Performance implications? Backwards compatibility?

Posted on December 22nd | 1 comment | Filed Under: GlobalizeRailsRuby | read on

View archives for December 2006.


About me

Cape Town
  • Currently living in Portugal
  • CV available on request
  • I do Travel Industry solutions and booking systems
  • I like i18n and L10n
  • I despise all things political
  • You may reach me @ +351 969622126,
  • Skype me with lourens.naude
  • or mail me at lourens@methodmissing.com