globalize-rails5 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +111 -0
- data/CONTRIBUTING.md +37 -0
- data/Gemfile +26 -0
- data/LICENSE +22 -0
- data/README.md +430 -0
- data/Rakefile +55 -0
- data/lib/globalize.rb +90 -0
- data/lib/globalize/active_record.rb +14 -0
- data/lib/globalize/active_record/act_macro.rb +111 -0
- data/lib/globalize/active_record/adapter.rb +99 -0
- data/lib/globalize/active_record/adapter_dirty.rb +54 -0
- data/lib/globalize/active_record/attributes.rb +26 -0
- data/lib/globalize/active_record/class_methods.rb +124 -0
- data/lib/globalize/active_record/exceptions.rb +13 -0
- data/lib/globalize/active_record/instance_methods.rb +218 -0
- data/lib/globalize/active_record/migration.rb +210 -0
- data/lib/globalize/active_record/query_methods.rb +98 -0
- data/lib/globalize/active_record/translation.rb +45 -0
- data/lib/globalize/interpolation.rb +28 -0
- data/lib/globalize/version.rb +3 -0
- data/lib/i18n/missing_translations_log_handler.rb +41 -0
- data/lib/i18n/missing_translations_raise_handler.rb +25 -0
- data/lib/patches/active_record/persistence.rb +17 -0
- data/lib/patches/active_record/query_method.rb +3 -0
- data/lib/patches/active_record/rails4/query_method.rb +35 -0
- data/lib/patches/active_record/rails4/uniqueness_validator.rb +42 -0
- data/lib/patches/active_record/rails5/uniqueness_validator.rb +47 -0
- data/lib/patches/active_record/relation.rb +12 -0
- data/lib/patches/active_record/serialization.rb +21 -0
- data/lib/patches/active_record/uniqueness_validator.rb +5 -0
- data/lib/patches/active_record/xml_attribute_serializer.rb +23 -0
- metadata +204 -0
@@ -0,0 +1,124 @@
|
|
1
|
+
module Globalize
|
2
|
+
module ActiveRecord
|
3
|
+
module ClassMethods
|
4
|
+
delegate :translated_locales, :set_translations_table_name, :to => :translation_class
|
5
|
+
|
6
|
+
if ::ActiveRecord::VERSION::STRING < "5.0.0"
|
7
|
+
def columns_hash
|
8
|
+
super.except(*translated_attribute_names.map(&:to_s))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def with_locales(*locales)
|
13
|
+
all.merge translation_class.with_locales(*locales)
|
14
|
+
end
|
15
|
+
|
16
|
+
def with_translations(*locales)
|
17
|
+
locales = translated_locales if locales.empty?
|
18
|
+
preload(:translations).joins(:translations).readonly(false).with_locales(locales).tap do |query|
|
19
|
+
query.distinct! unless locales.flatten.one?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def with_required_attributes
|
24
|
+
warn 'with_required_attributes is deprecated and will be removed in the next release of Globalize.'
|
25
|
+
required_translated_attributes.inject(all) do |scope, name|
|
26
|
+
scope.where("#{translated_column_name(name)} IS NOT NULL")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def with_translated_attribute(name, value, locales = Globalize.fallbacks)
|
31
|
+
with_translations.where(
|
32
|
+
translated_column_name(name) => value,
|
33
|
+
translated_column_name(:locale) => Array(locales).map(&:to_s)
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def translated?(name)
|
38
|
+
translated_attribute_names.include?(name.to_sym)
|
39
|
+
end
|
40
|
+
|
41
|
+
def required_attributes
|
42
|
+
warn 'required_attributes is deprecated and will be removed in the next release of Globalize.'
|
43
|
+
validators.map { |v| v.attributes if v.is_a?(ActiveModel::Validations::PresenceValidator) }.flatten
|
44
|
+
end
|
45
|
+
|
46
|
+
def required_translated_attributes
|
47
|
+
warn 'required_translated_attributes is deprecated and will be removed in the next release of Globalize.'
|
48
|
+
translated_attribute_names & required_attributes
|
49
|
+
end
|
50
|
+
|
51
|
+
def translation_class
|
52
|
+
@translation_class ||= begin
|
53
|
+
if self.const_defined?(:Translation, false)
|
54
|
+
klass = self.const_get(:Translation, false)
|
55
|
+
else
|
56
|
+
klass = self.const_set(:Translation, Class.new(Globalize::ActiveRecord::Translation))
|
57
|
+
end
|
58
|
+
|
59
|
+
klass.belongs_to :globalized_model, :class_name => self.name, :foreign_key => translation_options[:foreign_key], inverse_of: :translations
|
60
|
+
klass
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def translations_table_name
|
65
|
+
translation_class.table_name
|
66
|
+
end
|
67
|
+
|
68
|
+
def translated_column_name(name)
|
69
|
+
"#{translation_class.table_name}.#{name}"
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# Override the default relation method in order to return a subclass
|
75
|
+
# of ActiveRecord::Relation with custom finder methods for translated
|
76
|
+
# attributes.
|
77
|
+
def relation
|
78
|
+
super.extending!(QueryMethods)
|
79
|
+
end
|
80
|
+
|
81
|
+
protected
|
82
|
+
|
83
|
+
def define_translated_attr_reader(name)
|
84
|
+
define_method(name) do |*args|
|
85
|
+
Globalize::Interpolation.interpolate(name, self, args)
|
86
|
+
end
|
87
|
+
alias_method :"#{name}_before_type_cast", name
|
88
|
+
end
|
89
|
+
|
90
|
+
def define_translated_attr_writer(name)
|
91
|
+
define_method(:"#{name}=") do |value|
|
92
|
+
write_attribute(name, value)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def define_translated_attr_accessor(name)
|
97
|
+
define_translated_attr_reader(name)
|
98
|
+
define_translated_attr_writer(name)
|
99
|
+
end
|
100
|
+
|
101
|
+
def define_translations_reader(name)
|
102
|
+
define_method(:"#{name}_translations") do
|
103
|
+
hash = translated_attribute_by_locale(name)
|
104
|
+
globalize.stash.keys.each_with_object(hash) do |locale, result|
|
105
|
+
result[locale] = globalize.fetch_stash(locale, name) if globalize.stash_contains?(locale, name)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def define_translations_writer(name)
|
111
|
+
define_method(:"#{name}_translations=") do |value|
|
112
|
+
value.each do |(locale, _value)|
|
113
|
+
write_attribute name, _value, :locale => locale
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def define_translations_accessor(name)
|
119
|
+
define_translations_reader(name)
|
120
|
+
define_translations_writer(name)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
module Globalize
|
2
|
+
module ActiveRecord
|
3
|
+
module InstanceMethods
|
4
|
+
delegate :translated_locales, :to => :translations
|
5
|
+
|
6
|
+
def globalize
|
7
|
+
@globalize ||= Adapter.new(self)
|
8
|
+
end
|
9
|
+
|
10
|
+
def attributes
|
11
|
+
super.merge(translated_attributes)
|
12
|
+
end
|
13
|
+
|
14
|
+
def attributes=(new_attributes, *options)
|
15
|
+
super unless new_attributes.respond_to?(:stringify_keys) && new_attributes.present?
|
16
|
+
attributes = new_attributes.stringify_keys
|
17
|
+
with_given_locale(attributes) { super(attributes.except("locale"), *options) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def assign_attributes(new_attributes, *options)
|
21
|
+
super unless new_attributes.respond_to?(:stringify_keys) && new_attributes.present?
|
22
|
+
attributes = new_attributes.stringify_keys
|
23
|
+
with_given_locale(attributes) { super(attributes.except("locale"), *options) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def write_attribute(name, value, *args, &block)
|
27
|
+
return super(name, value, *args, &block) unless translated?(name)
|
28
|
+
|
29
|
+
options = {:locale => Globalize.locale}.merge(args.first || {})
|
30
|
+
|
31
|
+
globalize.write(options[:locale], name, value)
|
32
|
+
end
|
33
|
+
|
34
|
+
def [](attr_name)
|
35
|
+
if translated?(attr_name)
|
36
|
+
read_attribute(attr_name)
|
37
|
+
else
|
38
|
+
read_attribute(attr_name) { |n| missing_attribute(n, caller) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def read_attribute(name, options = {}, &block)
|
43
|
+
options = {:translated => true, :locale => nil}.merge(options)
|
44
|
+
return super(name, &block) unless options[:translated]
|
45
|
+
|
46
|
+
if translated?(name)
|
47
|
+
if !(value = globalize.fetch(options[:locale] || Globalize.locale, name)).nil?
|
48
|
+
value
|
49
|
+
else
|
50
|
+
super(name, &block)
|
51
|
+
end
|
52
|
+
else
|
53
|
+
super(name, &block)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def attribute_names
|
58
|
+
translated_attribute_names.map(&:to_s) + super
|
59
|
+
end
|
60
|
+
|
61
|
+
delegate :translated?, :to => :class
|
62
|
+
|
63
|
+
def translated_attributes
|
64
|
+
translated_attribute_names.inject({}) do |attributes, name|
|
65
|
+
attributes.merge(name.to_s => send(name))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# This method is basically the method built into Rails
|
70
|
+
# but we have to pass {:translated => false}
|
71
|
+
def untranslated_attributes
|
72
|
+
attribute_names.inject({}) do |attrs, name|
|
73
|
+
attrs[name] = read_attribute(name, {:translated => false}); attrs
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def set_translations(options)
|
78
|
+
options.keys.each do |locale|
|
79
|
+
translation = translation_for(locale) ||
|
80
|
+
translations.build(:locale => locale.to_s)
|
81
|
+
|
82
|
+
options[locale].each do |key, value|
|
83
|
+
translation.send :"#{key}=", value
|
84
|
+
translation.globalized_model.send :"#{key}=", value
|
85
|
+
end
|
86
|
+
translation.save if persisted?
|
87
|
+
end
|
88
|
+
globalize.reset
|
89
|
+
end
|
90
|
+
|
91
|
+
def reload(options = nil)
|
92
|
+
translation_caches.clear
|
93
|
+
translated_attribute_names.each { |name| @attributes.reset(name.to_s) }
|
94
|
+
globalize.reset
|
95
|
+
super(options)
|
96
|
+
end
|
97
|
+
|
98
|
+
def initialize_dup(other)
|
99
|
+
@globalize = nil
|
100
|
+
@translation_caches = nil
|
101
|
+
super
|
102
|
+
other.each_locale_and_translated_attribute do |locale, name|
|
103
|
+
globalize.write(locale, name, other.globalize.fetch(locale, name) )
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def translation
|
108
|
+
translation_for(::Globalize.locale)
|
109
|
+
end
|
110
|
+
|
111
|
+
def translation_for(locale, build_if_missing = true)
|
112
|
+
unless translation_caches[locale]
|
113
|
+
# Fetch translations from database as those in the translation collection may be incomplete
|
114
|
+
_translation = translations.detect{|t| t.locale.to_s == locale.to_s}
|
115
|
+
_translation ||= translations.with_locale(locale).first unless translations.loaded?
|
116
|
+
_translation ||= translations.build(:locale => locale) if build_if_missing
|
117
|
+
translation_caches[locale] = _translation if _translation
|
118
|
+
end
|
119
|
+
translation_caches[locale]
|
120
|
+
end
|
121
|
+
|
122
|
+
def translation_caches
|
123
|
+
@translation_caches ||= {}
|
124
|
+
end
|
125
|
+
|
126
|
+
def translations_by_locale
|
127
|
+
translations.each_with_object(HashWithIndifferentAccess.new) do |t, hash|
|
128
|
+
hash[t.locale] = block_given? ? yield(t) : t
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def translated_attribute_by_locale(name)
|
133
|
+
translations_by_locale(&:"#{name}")
|
134
|
+
end
|
135
|
+
|
136
|
+
# Get available locales from translations association, without a separate distinct query
|
137
|
+
def available_locales
|
138
|
+
translations.map(&:locale).uniq
|
139
|
+
end
|
140
|
+
|
141
|
+
def globalize_fallbacks(locale)
|
142
|
+
Globalize.fallbacks(locale)
|
143
|
+
end
|
144
|
+
|
145
|
+
def save(*)
|
146
|
+
result = Globalize.with_locale(translation.locale || I18n.default_locale) do
|
147
|
+
without_fallbacks do
|
148
|
+
super
|
149
|
+
end
|
150
|
+
end
|
151
|
+
if result
|
152
|
+
globalize.clear_dirty
|
153
|
+
end
|
154
|
+
|
155
|
+
result
|
156
|
+
end
|
157
|
+
|
158
|
+
def column_for_attribute name
|
159
|
+
return super if translated_attribute_names.exclude?(name)
|
160
|
+
|
161
|
+
globalize.send(:column_for_attribute, name)
|
162
|
+
end
|
163
|
+
|
164
|
+
def cache_key
|
165
|
+
[super, translation.cache_key].join("/")
|
166
|
+
end
|
167
|
+
|
168
|
+
def changed?
|
169
|
+
changed_attributes.present? || translations.any?(&:changed?)
|
170
|
+
end
|
171
|
+
|
172
|
+
# need to access instance variable directly since changed_attributes
|
173
|
+
# is frozen as of Rails 4.2
|
174
|
+
def original_changed_attributes
|
175
|
+
@changed_attributes
|
176
|
+
end
|
177
|
+
|
178
|
+
protected
|
179
|
+
|
180
|
+
def each_locale_and_translated_attribute
|
181
|
+
used_locales.each do |locale|
|
182
|
+
translated_attribute_names.each do |name|
|
183
|
+
yield locale, name
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def used_locales
|
189
|
+
locales = globalize.stash.keys.concat(globalize.stash.keys).concat(translations.translated_locales)
|
190
|
+
locales.uniq!
|
191
|
+
locales
|
192
|
+
end
|
193
|
+
|
194
|
+
def save_translations!
|
195
|
+
globalize.save_translations!
|
196
|
+
translation_caches.clear
|
197
|
+
end
|
198
|
+
|
199
|
+
def with_given_locale(_attributes, &block)
|
200
|
+
attributes = _attributes.stringify_keys
|
201
|
+
|
202
|
+
if locale = attributes.try(:delete, "locale")
|
203
|
+
Globalize.with_locale(locale, &block)
|
204
|
+
else
|
205
|
+
yield
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def without_fallbacks
|
210
|
+
before = self.fallbacks_for_empty_translations
|
211
|
+
self.fallbacks_for_empty_translations = false
|
212
|
+
yield
|
213
|
+
ensure
|
214
|
+
self.fallbacks_for_empty_translations = before
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module Globalize
|
4
|
+
module ActiveRecord
|
5
|
+
module Migration
|
6
|
+
def globalize_migrator
|
7
|
+
@globalize_migrator ||= Migrator.new(self)
|
8
|
+
end
|
9
|
+
|
10
|
+
delegate :create_translation_table!, :add_translation_fields!,
|
11
|
+
:drop_translation_table!, :translation_index_name,
|
12
|
+
:translation_locale_index_name, :to => :globalize_migrator
|
13
|
+
|
14
|
+
class Migrator
|
15
|
+
include Globalize::ActiveRecord::Exceptions
|
16
|
+
|
17
|
+
attr_reader :model
|
18
|
+
delegate :translated_attribute_names, :connection, :table_name,
|
19
|
+
:table_name_prefix, :translations_table_name, :columns, :to => :model
|
20
|
+
|
21
|
+
def initialize(model)
|
22
|
+
@model = model
|
23
|
+
end
|
24
|
+
|
25
|
+
def fields
|
26
|
+
@fields ||= complete_translated_fields
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_translation_table!(fields = {}, options = {})
|
30
|
+
extra = options.keys - [:migrate_data, :remove_source_columns, :unique_index]
|
31
|
+
if extra.any?
|
32
|
+
raise ArgumentError, "Unknown migration #{'option'.pluralize(extra.size)}: #{extra}"
|
33
|
+
end
|
34
|
+
@fields = fields
|
35
|
+
# If we have fields we only want to create the translation table with those fields
|
36
|
+
complete_translated_fields if fields.blank?
|
37
|
+
validate_translated_fields
|
38
|
+
|
39
|
+
create_translation_table
|
40
|
+
add_translation_fields!(fields, options)
|
41
|
+
create_translations_index(options)
|
42
|
+
clear_schema_cache!
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_translation_fields!(fields, options = {})
|
46
|
+
@fields = fields
|
47
|
+
validate_translated_fields
|
48
|
+
add_translation_fields
|
49
|
+
clear_schema_cache!
|
50
|
+
move_data_to_translation_table if options[:migrate_data]
|
51
|
+
remove_source_columns if options[:remove_source_columns]
|
52
|
+
clear_schema_cache!
|
53
|
+
end
|
54
|
+
|
55
|
+
def remove_source_columns
|
56
|
+
connection.remove_columns(table_name, *fields.keys)
|
57
|
+
end
|
58
|
+
|
59
|
+
def drop_translation_table!(options = {})
|
60
|
+
move_data_to_model_table if options[:migrate_data]
|
61
|
+
drop_translations_index
|
62
|
+
drop_translation_table
|
63
|
+
clear_schema_cache!
|
64
|
+
end
|
65
|
+
|
66
|
+
# This adds all the current translated attributes of the model
|
67
|
+
# It's a problem because in early migrations would add all the translated attributes
|
68
|
+
def complete_translated_fields
|
69
|
+
translated_attribute_names.each do |name|
|
70
|
+
@fields[name] ||= column_type(name)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_translation_table
|
75
|
+
connection.create_table(translations_table_name) do |t|
|
76
|
+
t.references table_name.sub(/^#{table_name_prefix}/, '').singularize, :null => false, :index => false, :type => column_type(model.primary_key).to_sym
|
77
|
+
t.string :locale, :null => false
|
78
|
+
t.timestamps :null => false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def add_translation_fields
|
83
|
+
connection.change_table(translations_table_name) do |t|
|
84
|
+
fields.each do |name, options|
|
85
|
+
if options.is_a? Hash
|
86
|
+
t.column name, options.delete(:type), options
|
87
|
+
else
|
88
|
+
t.column name, options
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_translations_index(options)
|
95
|
+
foreign_key = "#{table_name.sub(/^#{table_name_prefix}/, "").singularize}_id".to_sym
|
96
|
+
connection.add_index(
|
97
|
+
translations_table_name,
|
98
|
+
foreign_key,
|
99
|
+
:name => translation_index_name
|
100
|
+
)
|
101
|
+
# index for select('DISTINCT locale') call in translation.rb
|
102
|
+
connection.add_index(
|
103
|
+
translations_table_name,
|
104
|
+
:locale,
|
105
|
+
:name => translation_locale_index_name
|
106
|
+
)
|
107
|
+
|
108
|
+
if options[:unique_index]
|
109
|
+
connection.add_index(
|
110
|
+
translations_table_name,
|
111
|
+
[foreign_key, :locale],
|
112
|
+
:name => translation_unique_index_name,
|
113
|
+
unique: true
|
114
|
+
)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def drop_translation_table
|
119
|
+
connection.drop_table(translations_table_name)
|
120
|
+
end
|
121
|
+
|
122
|
+
def drop_translations_index
|
123
|
+
if connection.indexes(translations_table_name).map(&:name).include?(translation_index_name)
|
124
|
+
connection.remove_index(translations_table_name, :name => translation_index_name)
|
125
|
+
end
|
126
|
+
if connection.indexes(translations_table_name).map(&:name).include?(translation_locale_index_name)
|
127
|
+
connection.remove_index(translations_table_name, :name => translation_locale_index_name)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def move_data_to_translation_table
|
132
|
+
model.find_each do |record|
|
133
|
+
translation = record.translation_for(I18n.locale) || record.translations.build(:locale => I18n.locale)
|
134
|
+
fields.each do |attribute_name, attribute_type|
|
135
|
+
translation[attribute_name] = record.read_attribute(attribute_name, {:translated => false})
|
136
|
+
end
|
137
|
+
translation.save!
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def move_data_to_model_table
|
142
|
+
add_missing_columns
|
143
|
+
|
144
|
+
# Find all of the translated attributes for all records in the model.
|
145
|
+
all_translated_attributes = model.all.collect{|m| m.attributes}
|
146
|
+
all_translated_attributes.each do |translated_record|
|
147
|
+
# Create a hash containing the translated column names and their values.
|
148
|
+
translated_attribute_names.inject(fields_to_update={}) do |f, name|
|
149
|
+
f.update({name.to_sym => translated_record[name.to_s]})
|
150
|
+
end
|
151
|
+
|
152
|
+
# Now, update the actual model's record with the hash.
|
153
|
+
model.where(model.primary_key.to_sym => translated_record[model.primary_key]).update_all(fields_to_update)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def validate_translated_fields
|
158
|
+
fields.each do |name, options|
|
159
|
+
raise BadFieldName.new(name) unless valid_field_name?(name)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def column_type(name)
|
164
|
+
columns.detect { |c| c.name == name.to_s }.try(:type)
|
165
|
+
end
|
166
|
+
|
167
|
+
def valid_field_name?(name)
|
168
|
+
translated_attribute_names.include?(name)
|
169
|
+
end
|
170
|
+
|
171
|
+
def translation_index_name
|
172
|
+
truncate_index_name "index_#{translations_table_name}_on_#{table_name.singularize}_id"
|
173
|
+
end
|
174
|
+
|
175
|
+
def translation_locale_index_name
|
176
|
+
truncate_index_name "index_#{translations_table_name}_on_locale"
|
177
|
+
end
|
178
|
+
|
179
|
+
def translation_unique_index_name
|
180
|
+
truncate_index_name "index_#{translations_table_name}_on_#{table_name.singularize}_id_and_locale"
|
181
|
+
end
|
182
|
+
|
183
|
+
def clear_schema_cache!
|
184
|
+
connection.schema_cache.clear! if connection.respond_to? :schema_cache
|
185
|
+
model::Translation.reset_column_information
|
186
|
+
model.reset_column_information
|
187
|
+
end
|
188
|
+
|
189
|
+
private
|
190
|
+
|
191
|
+
def truncate_index_name(index_name)
|
192
|
+
if index_name.size < connection.index_name_length
|
193
|
+
index_name
|
194
|
+
else
|
195
|
+
"index_#{Digest::SHA1.hexdigest(index_name)}"[0, connection.index_name_length]
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def add_missing_columns
|
200
|
+
clear_schema_cache!
|
201
|
+
translated_attribute_names.map(&:to_s).each do |attribute|
|
202
|
+
unless model.column_names.include?(attribute)
|
203
|
+
connection.add_column(table_name, attribute, model::Translation.columns_hash[attribute].type)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|