summaryrefslogtreecommitdiff
path: root/vendor/plugins/globalize2/lib
diff options
context:
space:
mode:
authorhukl <contact@smyck.org>2009-10-06 20:54:47 +0200
committerhukl <contact@smyck.org>2009-10-06 20:54:47 +0200
commit2c59d78cde32cfd6f6fcda1f9aa78f94b38e5930 (patch)
tree23935202a8c45ae1997739d4173a3d9559e080e5 /vendor/plugins/globalize2/lib
parentcd6ebe068cf42badc07ea0d803476ef4b1be3177 (diff)
updated globalize2
Diffstat (limited to 'vendor/plugins/globalize2/lib')
-rw-r--r--vendor/plugins/globalize2/lib/globalize/model/active_record.rb17
-rw-r--r--vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb86
2 files changed, 60 insertions, 43 deletions
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'
6module Globalize 6module Globalize
7 module Model 7 module Model
8 module ActiveRecord 8 module ActiveRecord
9 class << self 9 class << self
10 def create_proxy_class(klass) 10 def create_proxy_class(klass)
11 Object.const_set "#{klass.name}Translation", Class.new(::ActiveRecord::Base){ 11 module_names = klass.name.split('::')
12 belongs_to "#{klass.name.underscore}".intern 12 klass_name = module_names.pop
13 13 target = module_names.empty? ? Object : module_names.join('::').constantize
14
15 target.const_set "#{klass_name}Translation", Class.new(::ActiveRecord::Base) {
16 belongs_to "#{klass.name.underscore.gsub('/', '_')}".intern
17
14 def locale 18 def locale
15 read_attribute(:locale).to_sym 19 read_attribute(:locale).to_sym
16 end 20 end
17 21
18 def locale=(locale) 22 def locale=(locale)
19 write_attribute(:locale, locale.to_s) 23 write_attribute(:locale, locale.to_s)
20 end 24 end
@@ -26,6 +30,9 @@ module Globalize
26 klass.send :define_method, attr_name, lambda { 30 klass.send :define_method, attr_name, lambda {
27 globalize.fetch self.class.locale, attr_name 31 globalize.fetch self.class.locale, attr_name
28 } 32 }
33 klass.send :define_method, "#{attr_name}_before_type_cast", lambda {
34 globalize.fetch self.class.locale, attr_name
35 }
29 klass.send :define_method, "#{attr_name}=", lambda {|val| 36 klass.send :define_method, "#{attr_name}=", lambda {|val|
30 globalize.stash self.class.locale, attr_name, val 37 globalize.stash self.class.locale, attr_name, val
31 self[attr_name] = val 38 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 @@
1require 'digest/sha1'
2
1module Globalize 3module Globalize
2 module Model 4 module Model
3
4 class MigrationError < StandardError; end 5 class MigrationError < StandardError; end
5 class UntranslatedMigrationField < MigrationError; end
6 class MigrationMissingTranslatedField < MigrationError; end 6 class MigrationMissingTranslatedField < MigrationError; end
7 class BadMigrationFieldType < MigrationError; end 7 class BadMigrationFieldType < MigrationError; end
8 8
9 module ActiveRecord 9 module ActiveRecord
10 module Translated 10 module Translated
11 def self.included(base) 11 def self.included(base)
@@ -20,10 +20,10 @@ module Globalize
20 # Only set up once per class 20 # Only set up once per class
21 unless included_modules.include? InstanceMethods 21 unless included_modules.include? InstanceMethods
22 class_inheritable_accessor :globalize_options, :globalize_proxy 22 class_inheritable_accessor :globalize_options, :globalize_proxy
23 23
24 include InstanceMethods 24 include InstanceMethods
25 extend ClassMethods 25 extend ClassMethods
26 26
27 self.globalize_proxy = Globalize::Model::ActiveRecord.create_proxy_class(self) 27 self.globalize_proxy = Globalize::Model::ActiveRecord.create_proxy_class(self)
28 has_many( 28 has_many(
29 :globalize_translations, 29 :globalize_translations,
@@ -33,40 +33,40 @@ module Globalize
33 :foreign_key => class_name.foreign_key 33 :foreign_key => class_name.foreign_key
34 ) 34 )
35 35
36 after_save :update_globalize_record 36 after_save :update_globalize_record
37 end 37 end
38 38
39 self.globalize_options = options 39 self.globalize_options = options
40 Globalize::Model::ActiveRecord.define_accessors(self, attr_names) 40 Globalize::Model::ActiveRecord.define_accessors(self, attr_names)
41 41
42 # Import any callbacks that have been defined by extensions to Globalize2 42 # Import any callbacks that have been defined by extensions to Globalize2
43 # and run them. 43 # and run them.
44 extend Callbacks 44 extend Callbacks
45 Callbacks.instance_methods.each {|cb| send cb } 45 Callbacks.instance_methods.each { |callback| send(callback) }
46 end 46 end
47 47
48 def locale=(locale) 48 def locale=(locale)
49 @@locale = locale 49 @@locale = locale
50 end 50 end
51 51
52 def locale 52 def locale
53 (defined?(@@locale) && @@locale) || I18n.locale 53 (defined?(@@locale) && @@locale) || I18n.locale
54 end 54 end
55 end 55 end
56 56
57 # Dummy Callbacks module. Extensions to Globalize2 can insert methods into here 57 # Dummy Callbacks module. Extensions to Globalize2 can insert methods into here
58 # and they'll be called at the end of the translates class method. 58 # and they'll be called at the end of the translates class method.
59 module Callbacks 59 module Callbacks
60 end 60 end
61 61
62 # Extension to the has_many :globalize_translations association 62 # Extension to the has_many :globalize_translations association
63 module Extensions 63 module Extensions
64 def by_locales(locales) 64 def by_locales(locales)
65 find :all, :conditions => { :locale => locales.map(&:to_s) } 65 find :all, :conditions => { :locale => locales.map(&:to_s) }
66 end 66 end
67 end 67 end
68 68
69 module ClassMethods 69 module ClassMethods
70 def method_missing(method, *args) 70 def method_missing(method, *args)
71 if method.to_s =~ /^find_by_(\w+)$/ && globalize_options[:translated_attributes].include?($1.to_sym) 71 if method.to_s =~ /^find_by_(\w+)$/ && globalize_options[:translated_attributes].include?($1.to_sym)
72 find(:first, :joins => :globalize_translations, 72 find(:first, :joins => :globalize_translations,
@@ -76,77 +76,87 @@ module Globalize
76 super 76 super
77 end 77 end
78 end 78 end
79 79
80 def create_translation_table!(fields) 80 def create_translation_table!(fields)
81 translated_fields = self.globalize_options[:translated_attributes] 81 translated_fields = self.globalize_options[:translated_attributes]
82 translated_fields.each do |f| 82 translated_fields.each do |f|
83 raise MigrationMissingTranslatedField, "Missing translated field #{f}" unless fields[f] 83 raise MigrationMissingTranslatedField, "Missing translated field #{f}" unless fields[f]
84 end 84 end
85
85 fields.each do |name, type| 86 fields.each do |name, type|
86 unless translated_fields.member? name 87 if translated_fields.include?(name) && ![:string, :text].include?(type)
87 raise UntranslatedMigrationField, "Can't migrate untranslated field: #{name}"
88 end
89 unless [ :string, :text ].member? type
90 raise BadMigrationFieldType, "Bad field type for #{name}, should be :string or :text" 88 raise BadMigrationFieldType, "Bad field type for #{name}, should be :string or :text"
91 end 89 end
92 end 90 end
93 translation_table_name = self.name.underscore + '_translations' 91
94 self.connection.create_table(translation_table_name) do |t| 92 self.connection.create_table(translation_table_name) do |t|
95 t.references self.table_name.singularize 93 t.references self.table_name.singularize
96 t.string :locale 94 t.string :locale
97 fields.each do |name, type| 95 fields.each do |name, type|
98 t.column name, type 96 t.column name, type
99 end 97 end
100 t.timestamps 98 t.timestamps
101 end 99 end
100
101 self.connection.add_index(translation_table_name, "#{self.table_name.singularize}_id", :name => translation_index_name)
102 end
103
104 def translation_table_name
105 self.name.underscore.gsub('/', '_') + '_translations'
106 end
107
108 def translation_index_name
109 # FIXME what's the max size of an index name?
110 index_name = "index_#{translation_table_name}_on_#{self.table_name.singularize}_id"
111 index_name.size < 50 ? index_name : "index_#{Digest::SHA1.hexdigest(index_name)}"
102 end 112 end
103 113
104 def drop_translation_table! 114 def drop_translation_table!
105 translation_table_name = self.name.underscore + '_translations' 115 self.connection.remove_index(translation_table_name, :name => translation_index_name)
106 self.connection.drop_table translation_table_name 116 self.connection.drop_table translation_table_name
107 end 117 end
108 118
109 private 119 private
110 120
111 def i18n_attr(attribute_name) 121 def i18n_attr(attribute_name)
112 self.base_class.name.underscore + "_translations.#{attribute_name}" 122 self.base_class.name.underscore.gsub('/', '_') + "_translations.#{attribute_name}"
113 end 123 end
114 end 124 end
115 125
116 module InstanceMethods 126 module InstanceMethods
117 def reload(options = nil) 127 def reload(options = nil)
118 globalize.clear 128 globalize.clear
119 129
120 # clear all globalized attributes 130 # clear all globalized attributes
121 # TODO what's the best way to handle this? 131 # TODO what's the best way to handle this?
122 self.class.globalize_options[:translated_attributes].each do |attr| 132 self.class.globalize_options[:translated_attributes].each do |attr|
123 @attributes.delete attr.to_s 133 @attributes.delete(attr.to_s)
124 end 134 end
125 135
126 super options 136 super(options)
127 end 137 end
128 138
129 def globalize 139 def globalize
130 @globalize ||= Adapter.new self 140 @globalize ||= Adapter.new self
131 end 141 end
132 142
133 def update_globalize_record 143 def update_globalize_record
134 globalize.update_translations! 144 globalize.update_translations!
135 end 145 end
136 146
137 def translated_locales 147 def translated_locales
138 globalize_translations.scoped(:select => 'DISTINCT locale').map {|gt| gt.locale.to_sym } 148 globalize_translations.scoped(:select => 'DISTINCT locale').map do |translation|
149 translation.locale.to_sym
150 end
139 end 151 end
140 152
141 def set_translations options 153 def set_translations options
142 options.keys.each do |key| 154 options.keys.each do |key|
143
144 translation = globalize_translations.find_by_locale(key.to_s) || 155 translation = globalize_translations.find_by_locale(key.to_s) ||
145 globalize_translations.build(:locale => key.to_s) 156 globalize_translations.build(:locale => key.to_s)
146 translation.update_attributes!(options[key]) 157 translation.update_attributes!(options[key])
147 end 158 end
148 end 159 end
149
150 end 160 end
151 end 161 end
152 end 162 end