Module: Globalize::ActiveRecord::InstanceMethods

Defined in:
lib/globalize/active_record/instance_methods.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/globalize/active_record/instance_methods.rb', line 14

def self.included(base)
  # Maintain Rails 3.0.x compatibility while adding Rails 3.1.x compatibility
  if base.method_defined?(:assign_attributes)
    base.class_eval %{
      def assign_attributes(attributes, options = {})
        with_given_locale(attributes) { super }
      end
    }
  else
    base.class_eval %{
      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
    }
  end
end

Instance Method Details

#attribute_namesObject



87
88
89
# File 'lib/globalize/active_record/instance_methods.rb', line 87

def attribute_names
  translated_attribute_names.map(&:to_s) + super
end

#attributesObject



10
11
12
# File 'lib/globalize/active_record/instance_methods.rb', line 10

def attributes
  super.merge(translated_attributes)
end

#cloneObject



131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/globalize/active_record/instance_methods.rb', line 131

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

#column_for_attribute(name) ⇒ Object



171
172
173
# File 'lib/globalize/active_record/instance_methods.rb', line 171

def column_for_attribute name
  translated_attribute_names.include?(name) ? globalize.send(:column_for_attribute, name) : super
end

#globalizeObject



6
7
8
# File 'lib/globalize/active_record/instance_methods.rb', line 6

def globalize
  @globalize ||= Adapter.new(self)
end

#globalize_fallbacks(locale) ⇒ Object



163
164
165
# File 'lib/globalize/active_record/instance_methods.rb', line 163

def globalize_fallbacks(locale)
  Globalize.fallbacks(locale)
end

#read_attribute(name, options = {}) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/globalize/active_record/instance_methods.rb', line 68

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]
    if (value = globalize.fetch(options[:locale] || Globalize.locale, name))
      value
    else
      super(name)
    end
  else
    super(name)
  end
end

#reload(options = nil) ⇒ Object



124
125
126
127
128
129
# File 'lib/globalize/active_record/instance_methods.rb', line 124

def reload(options = nil)
  translation_caches.clear
  translated_attribute_names.each { |name| @attributes.delete(name.to_s) }
  globalize.reset
  super(options)
end

#rollbackObject



167
168
169
# File 'lib/globalize/active_record/instance_methods.rb', line 167

def rollback
  translation_caches[::Globalize.locale] = translation.previous_version
end

#set_translations(options) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/globalize/active_record/instance_methods.rb', line 111

def set_translations(options)
  options.keys.each do |locale|
    translation = translation_for(locale) ||
                  translations.build(:locale => locale.to_s)

    options[locale].each do |key, value|
      translation.send :"#{key}=", value
    end
    translation.save
  end
  globalize.reset
end

#translated?(name) ⇒ Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/globalize/active_record/instance_methods.rb', line 91

def translated?(name)
  self.class.translated?(name)
end

#translated_attributesObject



95
96
97
98
99
# File 'lib/globalize/active_record/instance_methods.rb', line 95

def translated_attributes
  translated_attribute_names.inject({}) do |attributes, name|
    attributes.merge(name.to_s => translation.send(name))
  end
end

#translationObject



144
145
146
# File 'lib/globalize/active_record/instance_methods.rb', line 144

def translation
  translation_for(::Globalize.locale)
end

#translation_cachesObject



159
160
161
# File 'lib/globalize/active_record/instance_methods.rb', line 159

def translation_caches
  @translation_caches ||= {}
end

#translation_for(locale, build_if_missing = true) ⇒ Object



148
149
150
151
152
153
154
155
156
157
# File 'lib/globalize/active_record/instance_methods.rb', line 148

def translation_for(locale, build_if_missing = true)
  unless translation_caches[locale]
    # Fetch translations from database as those in the translation collection may be incomplete
    _translation = translations.detect{|t| t.locale.to_s == locale.to_s}
    _translation ||= translations.with_locale(locale).first unless translations.loaded?
    _translation ||= translations.build(:locale => locale) if build_if_missing
    translation_caches[locale] = _translation if _translation
  end
  translation_caches[locale]
end

#untranslated_attributesObject

This method is basically the method built into Rails but we have to pass => false



103
104
105
106
107
108
109
# File 'lib/globalize/active_record/instance_methods.rb', line 103

def untranslated_attributes
  attrs = {}
  attribute_names.each do |name|
    attrs[name] = read_attribute(name, {:translated => false})
  end
  attrs
end

#write_attribute(name, value, options = {}) ⇒ Object



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
# File 'lib/globalize/active_record/instance_methods.rb', line 39

def write_attribute(name, value, options = {})
  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 => Globalize.locale}.merge(options)
    
    # Dirty tracking, paraphrased from
    # ActiveRecord::AttributeMethods::Dirty#write_attribute.
    name_str = name.to_s
    if attribute_changed?(name_str)
      # If there's already a change, delete it if this undoes the change.
      old = changed_attributes[name_str]
      changed_attributes.delete(name_str) if value == old
    else
      # If there's not a change yet, record it.
      old = globalize.fetch(options[:locale], name)
      old = old.clone if old.duplicable?
      changed_attributes[name_str] = old if value != old
    end
    
    globalize.write(options[:locale], name, value)
  else
    super(name, value)
  end
end