From 2c59d78cde32cfd6f6fcda1f9aa78f94b38e5930 Mon Sep 17 00:00:00 2001 From: hukl Date: Tue, 6 Oct 2009 20:54:47 +0200 Subject: updated globalize2 --- .../lib/globalize/model/active_record.rb | 17 +++-- .../globalize/model/active_record/translated.rb | 86 ++++++++++++---------- 2 files changed, 60 insertions(+), 43 deletions(-) (limited to 'vendor/plugins/globalize2/lib') diff --git a/vendor/plugins/globalize2/lib/globalize/model/active_record.rb b/vendor/plugins/globalize2/lib/globalize/model/active_record.rb index 9645842..9218054 100644 --- a/vendor/plugins/globalize2/lib/globalize/model/active_record.rb +++ b/vendor/plugins/globalize2/lib/globalize/model/active_record.rb @@ -6,15 +6,19 @@ require 'globalize/model/active_record/translated' module Globalize module Model module ActiveRecord - class << self + class << self def create_proxy_class(klass) - Object.const_set "#{klass.name}Translation", Class.new(::ActiveRecord::Base){ - belongs_to "#{klass.name.underscore}".intern - + module_names = klass.name.split('::') + klass_name = module_names.pop + target = module_names.empty? ? Object : module_names.join('::').constantize + + target.const_set "#{klass_name}Translation", Class.new(::ActiveRecord::Base) { + belongs_to "#{klass.name.underscore.gsub('/', '_')}".intern + def locale read_attribute(:locale).to_sym end - + def locale=(locale) write_attribute(:locale, locale.to_s) end @@ -26,6 +30,9 @@ module Globalize klass.send :define_method, attr_name, lambda { globalize.fetch self.class.locale, attr_name } + klass.send :define_method, "#{attr_name}_before_type_cast", lambda { + globalize.fetch self.class.locale, attr_name + } klass.send :define_method, "#{attr_name}=", lambda {|val| globalize.stash self.class.locale, attr_name, val self[attr_name] = val diff --git a/vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb b/vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb index f8fb230..4f75c8a 100644 --- a/vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb +++ b/vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb @@ -1,11 +1,11 @@ +require 'digest/sha1' + module Globalize module Model - class MigrationError < StandardError; end - class UntranslatedMigrationField < MigrationError; end class MigrationMissingTranslatedField < MigrationError; end class BadMigrationFieldType < MigrationError; end - + module ActiveRecord module Translated def self.included(base) @@ -20,10 +20,10 @@ module Globalize # Only set up once per class unless included_modules.include? InstanceMethods class_inheritable_accessor :globalize_options, :globalize_proxy - + include InstanceMethods extend ClassMethods - + self.globalize_proxy = Globalize::Model::ActiveRecord.create_proxy_class(self) has_many( :globalize_translations, @@ -33,40 +33,40 @@ module Globalize :foreign_key => class_name.foreign_key ) - after_save :update_globalize_record + after_save :update_globalize_record end self.globalize_options = options Globalize::Model::ActiveRecord.define_accessors(self, attr_names) - + # Import any callbacks that have been defined by extensions to Globalize2 # and run them. extend Callbacks - Callbacks.instance_methods.each {|cb| send cb } + Callbacks.instance_methods.each { |callback| send(callback) } end def locale=(locale) @@locale = locale end - + def locale (defined?(@@locale) && @@locale) || I18n.locale - end + end end # Dummy Callbacks module. Extensions to Globalize2 can insert methods into here # and they'll be called at the end of the translates class method. module Callbacks end - + # Extension to the has_many :globalize_translations association module Extensions def by_locales(locales) find :all, :conditions => { :locale => locales.map(&:to_s) } end end - - module ClassMethods + + module ClassMethods def method_missing(method, *args) if method.to_s =~ /^find_by_(\w+)$/ && globalize_options[:translated_attributes].include?($1.to_sym) find(:first, :joins => :globalize_translations, @@ -76,77 +76,87 @@ module Globalize super end end - + def create_translation_table!(fields) translated_fields = self.globalize_options[:translated_attributes] translated_fields.each do |f| raise MigrationMissingTranslatedField, "Missing translated field #{f}" unless fields[f] end + fields.each do |name, type| - unless translated_fields.member? name - raise UntranslatedMigrationField, "Can't migrate untranslated field: #{name}" - end - unless [ :string, :text ].member? type + if translated_fields.include?(name) && ![:string, :text].include?(type) raise BadMigrationFieldType, "Bad field type for #{name}, should be :string or :text" - end + end end - translation_table_name = self.name.underscore + '_translations' + self.connection.create_table(translation_table_name) do |t| t.references self.table_name.singularize t.string :locale fields.each do |name, type| t.column name, type end - t.timestamps + t.timestamps end + + self.connection.add_index(translation_table_name, "#{self.table_name.singularize}_id", :name => translation_index_name) + end + + def translation_table_name + self.name.underscore.gsub('/', '_') + '_translations' + end + + def translation_index_name + # FIXME what's the max size of an index name? + index_name = "index_#{translation_table_name}_on_#{self.table_name.singularize}_id" + index_name.size < 50 ? index_name : "index_#{Digest::SHA1.hexdigest(index_name)}" end def drop_translation_table! - translation_table_name = self.name.underscore + '_translations' + self.connection.remove_index(translation_table_name, :name => translation_index_name) self.connection.drop_table translation_table_name end - + private - + def i18n_attr(attribute_name) - self.base_class.name.underscore + "_translations.#{attribute_name}" - end + self.base_class.name.underscore.gsub('/', '_') + "_translations.#{attribute_name}" + end end - + module InstanceMethods def reload(options = nil) globalize.clear - + # clear all globalized attributes # TODO what's the best way to handle this? self.class.globalize_options[:translated_attributes].each do |attr| - @attributes.delete attr.to_s + @attributes.delete(attr.to_s) end - - super options + + super(options) end - + def globalize @globalize ||= Adapter.new self end - + def update_globalize_record globalize.update_translations! end - + def translated_locales - globalize_translations.scoped(:select => 'DISTINCT locale').map {|gt| gt.locale.to_sym } + globalize_translations.scoped(:select => 'DISTINCT locale').map do |translation| + translation.locale.to_sym + end end - + def set_translations options options.keys.each do |key| - translation = globalize_translations.find_by_locale(key.to_s) || globalize_translations.build(:locale => key.to_s) translation.update_attributes!(options[key]) end end - end end end -- cgit v1.3