| Module | Globalize::DbTranslate::TranslateClassMethods |
| In: |
vendor/plugins/globalize/lib/globalize/localization/db_translate.rb
|
This is a replacement for the standard ActiveRecord find method. Use it in the exact same way you would the regular find, except for the following provisos:
be described below.
find returns the retreived models, with all translated fields correctly loaded, depending on the active language.
:include_translated works as follows: any model specified in the :include_translated option will be eagerly loaded and added to the current model as attributes, prefixed with the name of the associated model. This is often referred to as piggybacking.
Example:
class Product < ActiveRecord::Base
belongs_to :manufacturer
belongs_to :category
end
class Category < ActiveRecord::Base
has_many :products
translates :name
end
prods = Product.find(:all, :include_translated => [ :manufacturer, :category ])
prods.first.category_name -> "batedeira"
# File vendor/plugins/globalize/lib/globalize/localization/db_translate.rb, line 317
317: def find(*args)
318: options = args.last.is_a?(Hash) ? args.last : {}
319:
320: return globalize_old_find(*args) if options[:untranslated]
321:
322: find_type = args.first
323: if find_type == :first
324: options[:translate_all] = true
325: return globalize_old_find(:first, options)
326: elsif find_type != :all
327: return globalize_old_find(*args)
328: end
329:
330: raise StandardError,
331: ":select option not allowed on translatable models " +
332: "(#{options[:select]})" if options[:select] && !options[:select].empty?
333:
334: # do quick version if base language is active
335: if Locale.base? && !options.has_key?(:include_translated)
336: results = untranslated_find(*args)
337: results.each {|result|
338: result.set_original_language
339: }
340: return results
341: end
342:
343: options[:conditions] = fix_conditions(options[:conditions]) if options[:conditions]
344:
345: # there will at least be an +id+ field here
346: select_clause = untranslated_fields.map {|f| "#{table_name}.#{f}" }.join(", ")
347:
348: joins_clause = options[:joins].nil? ? "" : options[:joins].dup
349: joins_args = []
350: load_full = options[:translate_all]
351: facets = load_full ? globalize_facets : preload_facets
352:
353: if Locale.base?
354: select_clause << ', ' << facets.map {|f| "#{table_name}.#{f}" }.join(", ")
355: else
356: language_id = Locale.active.language.id
357: load_full = options[:translate_all]
358: facets = load_full ? globalize_facets : preload_facets
359:
360: ??
361:
362: # sqlite bug hack
363: select_position = untranslated_fields.size
364:
365: # initialize where tweaking
366: if options[:conditions].nil?
367: where_clause = ""
368: else
369: if options[:conditions].kind_of? Array
370: conditions_is_array = true
371: where_clause = options[:conditions].shift
372: else
373: where_clause = options[:conditions]
374: end
375: end
376:
377: facets.each do |facet|
378: facet = facet.to_s
379: facet_table_alias = "t_#{facet}"
380:
381: # sqlite bug hack
382: select_position += 1
383: options[:order].sub!(/\b#{facet}\b/, select_position.to_s) if options[:order] if sqlite?
384:
385: select_clause << ", COALESCE(#{facet_table_alias}.text, #{table_name}.#{facet}) AS #{facet}, "
386: select_clause << " #{facet_table_alias}.text AS #{facet}_not_base "
387: joins_clause << " LEFT OUTER JOIN globalize_translations AS #{facet_table_alias} " +
388: "ON #{facet_table_alias}.table_name = ? " +
389: "AND #{table_name}.#{primary_key} = #{facet_table_alias}.item_id " +
390: "AND #{facet_table_alias}.facet = ? AND #{facet_table_alias}.language_id = ? "
391: joins_args << table_name << facet << language_id
392:
393: #for translated fields inside WHERE clause substitute corresponding COALESCE string
394: where_clause.gsub!(/((((#{table_name}\.)|\W)#{facet})|^#{facet})\W/, " COALESCE(#{facet_table_alias}.text, #{table_name}.#{facet}) ")
395: end
396:
397: options[:conditions] = sanitize_sql(
398: conditions_is_array ? [ where_clause ] + options[:conditions] : where_clause
399: ) unless options[:conditions].nil?
400: end
401:
402: # add in associations (of :belongs_to nature) if applicable
403: associations = options[:include_translated] || []
404: associations = [ associations ].flatten
405: associations.each do |assoc|
406: rfxn = reflect_on_association(assoc)
407: assoc_type = rfxn.macro
408: raise StandardError,
409: ":include_translated associations must be of type :belongs_to;" +
410: "#{assoc} is #{assoc_type}" if assoc_type != :belongs_to
411: klass = rfxn.klass
412: assoc_facets = klass.preload_facets
413: included_table = klass.table_name
414: included_fk = klass.primary_key
415: fk = rfxn.options[:foreign_key] || "#{assoc}_id"
416: assoc_facets.each do |facet|
417: facet_table_alias = "t_#{assoc}_#{facet}"
418:
419: if Locale.base?
420: select_clause << ", #{included_table}.#{facet} AS #{assoc}_#{facet} "
421: else
422: select_clause << ", COALESCE(#{facet_table_alias}.text, #{included_table}.#{facet}) " +
423: "AS #{assoc}_#{facet} "
424: joins_clause << " LEFT OUTER JOIN globalize_translations AS #{facet_table_alias} " +
425: "ON #{facet_table_alias}.table_name = ? " +
426: "AND #{table_name}.#{fk} = #{facet_table_alias}.item_id " +
427: "AND #{facet_table_alias}.facet = ? AND #{facet_table_alias}.language_id = ? "
428: joins_args << klass.table_name << facet.to_s << language_id
429: end
430: end
431: joins_clause << "LEFT OUTER JOIN #{included_table} " +
432: "ON #{table_name}.#{fk} = #{included_table}.#{included_fk} "
433: end
434:
435: options[:select] = select_clause
436: options[:readonly] = false
437:
438: sanitized_joins_clause = sanitize_sql( [ joins_clause, *joins_args ] )
439: options[:joins] = sanitized_joins_clause
440: results = globalize_old_find(:all, options)
441:
442: results.each {|result|
443: result.set_original_language
444: result.fully_loaded = true if load_full
445: }
446: end
Use this instead of find if you want to bypass the translation code for any reason.
# File vendor/plugins/globalize/lib/globalize/localization/db_translate.rb, line 457
457: def untranslated_find(*args)
458: has_options = args.last.is_a?(Hash)
459: options = has_options ? args.last : {}
460: options[:untranslated] = true
461: args << options if !has_options
462: globalize_old_find(*args)
463: end