forked from globalize/globalize
/
instance_methods.rb
166 lines (139 loc) · 5 KB
/
instance_methods.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
module Globalize
module ActiveRecord
module InstanceMethods
delegate :translated_locales, :to => :translations
def globalize
@globalize ||= Adapter.new(self)
end
def attributes
super.merge(translated_attributes)
end
def attributes=(attributes, *args)
with_given_locale(attributes) { super }
end
def update_attributes!(attributes, *args)
with_given_locale(attributes) { super }
end
def update_attributes(attributes, *args)
with_given_locale(attributes) { super }
end
def write_attribute(name, value, options = {})
# raise 'y' if value.nil? # TODO.
if translated?(name)
# Deprecate old use of locale
unless options.is_a?(Hash)
warn "[DEPRECATION] passing 'locale' as #{options.inspect} is deprecated. Please use {:locale => #{options.inspect}} instead."
options = {:locale => options}
end
options = {:locale => nil}.merge(options)
attribute_will_change! name.to_s
globalize.write(options[:locale] || Globalize.locale, name, value)
else
super(name, value)
end
end
def read_attribute(name, options = {})
# Deprecate old use of locale
unless options.is_a?(Hash)
warn "[DEPRECATION] passing 'locale' as #{options.inspect} is deprecated. Please use {:locale => #{options.inspect}} instead."
options = {:locale => options}
end
options = {:translated => true, :locale => nil}.merge(options)
if self.class.translated?(name) and options[:translated]
globalize.fetch(options[:locale] || Globalize.locale, name)
else
super(name)
end
end
def attribute_names
translated_attribute_names.map(&:to_s) + super
end
def translated?(name)
self.class.translated?(name)
end
def translated_attributes
translated_attribute_names.inject({}) do |attributes, name|
attributes.merge(name.to_s => translation.send(name))
end
end
# This method is basically the method built into Rails
# but we have to pass {:translated => false}
def untranslated_attributes
attrs = {}
attribute_names.each do |name|
attrs[name] = read_attribute(name, {:translated => false})
end
attrs
end
def set_translations(options)
options.keys.each do |locale|
translation = translation_for(locale) ||
translations.build(:locale => locale.to_s)
translation.update_attributes!(options[locale])
end
end
def reload(options = nil)
translated_attribute_names.each { |name| @attributes.delete(name.to_s) }
globalize.reset
super(options)
end
def clone
obj = super
return obj unless respond_to?(:translated_attribute_names)
obj.instance_variable_set(:@translations, nil) if new_record? # Reset the collection because of rails bug: http://pastie.org/1521874
obj.instance_variable_set(:@globalize, nil )
each_locale_and_translated_attribute do |locale, name|
obj.globalize.write(locale, name, globalize.fetch(locale, name) )
end
return obj
end
def translation
translation_for(::Globalize.locale)
end
def translation_for(locale)
@translation_caches ||= {}
unless @translation_caches[locale]
# Enumberable#detect is better since we have the translations collection (already) loaded
# using either Model.includes(:translations) or Model.with_translations
_translation = translations.detect{|t| t.locale.to_s == locale.to_s}
_translation ||= translations.build(:locale => locale)
@translation_caches[locale] = _translation
end
@translation_caches[locale]
end
def rollback
@translation_caches[::Globalize.locale] = translation.previous_version
end
protected
def each_locale_and_translated_attribute
used_locales.each do |locale|
translated_attribute_names.each do |name|
yield locale, name
end
end
end
def used_locales
locales = globalize.stash.keys.concat(globalize.stash.keys).concat(translations.translated_locales)
locales.uniq!
locales
end
def update_checkers!
Globalize.available_locales.each do |locale|
self["is_locale_#{locale}"] = !globalize.all_blank?(locale, translated_attribute_names)
end
end
def save_translations!
globalize.save_translations!
@translation_caches = {}
end
def with_given_locale(attributes, &block)
attributes.symbolize_keys! if attributes.respond_to?(:symbolize_keys!)
if locale = attributes.try(:delete, :locale)
Globalize.with_locale(locale, &block)
else
yield
end
end
end
end
end