globalize 4.0.3 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1d86330a6d33c2690020a923b34f33212f334d33
4
- data.tar.gz: c4295ec69aed48ffa104e98384b57fedd8e627f8
3
+ metadata.gz: 2eeaeaa894fcfa1bda7a09f0082888c1daeb2867
4
+ data.tar.gz: e66a9181bbf984d8ecd2d3e37c70de70d944733a
5
5
  SHA512:
6
- metadata.gz: 969f5f26a04dc4ee0a79d569cb771bac063198f2fe9624ca627e4fe602298b4a204237eba4a08e470d70856eeb955fed65d2b4d5b62281dd8a4ade974cc71b66
7
- data.tar.gz: e4de5115385b47cc9c699421dd53b3348377133e3b47ea2606b59945d9c3983bad1911efb5e5b8a6885ad2149517ff54ca45a780316126fcfdee3031ba56a67c
6
+ metadata.gz: 3c0d7d63119d1b46a47b3a33466a23ad153656678b8c98fda5345e3e36f7d7b1794fc00368140d9826307e8fe3ae4e6cef5d04404f3ae04d3b277141e6dffaeb
7
+ data.tar.gz: 36ab294d22cb53542122c8e2111020445ec1f9495def8d4ea9daecf2d9d6a81a4bb2fd50798d585f0d2cba1fc77024c7f5f9c97c632707b2b24d99396995c8cf
@@ -1,5 +1,8 @@
1
1
  # Globalize Changelog
2
2
 
3
+ ## 5.0.0 (2014-03-03)
4
+ * Added support for Rails 4.2, but removed support for every previous version of Rails. This is a backward incompatible change, thus the version is now 5.0.0. (thanks [Nico Ritsche](https://github.com/ncri) and others). [#396](https://github.com/globalize/globalize/pull/396).
5
+
3
6
  ## 4.0.3 (2014-11-24)
4
7
  * Fixes a problem where after dup the dup'd model and the original model shared a translation instance, which means that if you mutate a translated field on the dup and save it, the original becomes a clone of the dup. [#352](https://github.com/globalize/globalize/pull/352).
5
8
  * Deprecated `with_required_attributes`, `required_attributes`, and `required_translated_attributes`. `with_translations` no longer invokes `with_required_attributes`. [#355](https://github.com/globalize/globalize/pull/355).
@@ -2,35 +2,36 @@ PATH
2
2
  remote: .
3
3
  specs:
4
4
  globalize (4.0.3)
5
- activemodel (>= 4.0.0, < 5)
6
- activerecord (>= 4.0.0, < 5)
5
+ activemodel (>= 4.2.0, < 4.3)
6
+ activerecord (>= 4.2.0, < 4.3)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activemodel (4.1.8)
12
- activesupport (= 4.1.8)
11
+ activemodel (4.2.0)
12
+ activesupport (= 4.2.0)
13
13
  builder (~> 3.1)
14
- activerecord (4.1.8)
15
- activemodel (= 4.1.8)
16
- activesupport (= 4.1.8)
17
- arel (~> 5.0.0)
18
- activesupport (4.1.8)
19
- i18n (~> 0.6, >= 0.6.9)
14
+ activerecord (4.2.0)
15
+ activemodel (= 4.2.0)
16
+ activesupport (= 4.2.0)
17
+ arel (~> 6.0)
18
+ activesupport (4.2.0)
19
+ i18n (~> 0.7)
20
20
  json (~> 1.7, >= 1.7.7)
21
21
  minitest (~> 5.1)
22
- thread_safe (~> 0.1)
22
+ thread_safe (~> 0.3, >= 0.3.4)
23
23
  tzinfo (~> 1.1)
24
24
  ansi (1.4.3)
25
- arel (5.0.1.20140414130214)
25
+ arel (6.0.0)
26
26
  builder (3.2.2)
27
27
  coderay (1.1.0)
28
- database_cleaner (1.3.0)
29
- i18n (0.6.11)
30
- json (1.8.1)
28
+ database_cleaner (1.4.0)
29
+ ffi2-generators (0.1.1)
30
+ i18n (0.7.0)
31
+ json (1.8.2)
31
32
  method_source (0.8.2)
32
- minitest (5.4.3)
33
- minitest-reporters (1.0.7)
33
+ minitest (5.5.1)
34
+ minitest-reporters (1.0.8)
34
35
  ansi
35
36
  builder
36
37
  minitest (>= 5.0)
@@ -41,10 +42,210 @@ GEM
41
42
  slop (~> 3.4)
42
43
  pry-nav (0.2.4)
43
44
  pry (>= 0.9.10, < 0.11.0)
44
- rake (10.3.2)
45
- rdoc (4.1.2)
46
- json (~> 1.4)
47
- ruby-progressbar (1.7.0)
45
+ rake (10.4.2)
46
+ rb-readline (0.5.2)
47
+ rdoc (4.2.0)
48
+ ruby-progressbar (1.7.1)
49
+ rubysl (2.1.0)
50
+ rubysl-abbrev (~> 2.0)
51
+ rubysl-base64 (~> 2.0)
52
+ rubysl-benchmark (~> 2.0)
53
+ rubysl-bigdecimal (~> 2.0)
54
+ rubysl-cgi (~> 2.0)
55
+ rubysl-cgi-session (~> 2.0)
56
+ rubysl-cmath (~> 2.0)
57
+ rubysl-complex (~> 2.0)
58
+ rubysl-continuation (~> 2.0)
59
+ rubysl-coverage (~> 2.0)
60
+ rubysl-csv (~> 2.0)
61
+ rubysl-curses (~> 2.0)
62
+ rubysl-date (~> 2.0)
63
+ rubysl-delegate (~> 2.0)
64
+ rubysl-digest (~> 2.0)
65
+ rubysl-drb (~> 2.0)
66
+ rubysl-e2mmap (~> 2.0)
67
+ rubysl-english (~> 2.0)
68
+ rubysl-enumerator (~> 2.0)
69
+ rubysl-erb (~> 2.0)
70
+ rubysl-etc (~> 2.0)
71
+ rubysl-expect (~> 2.0)
72
+ rubysl-fcntl (~> 2.0)
73
+ rubysl-fiber (~> 2.0)
74
+ rubysl-fileutils (~> 2.0)
75
+ rubysl-find (~> 2.0)
76
+ rubysl-forwardable (~> 2.0)
77
+ rubysl-getoptlong (~> 2.0)
78
+ rubysl-gserver (~> 2.0)
79
+ rubysl-io-console (~> 2.0)
80
+ rubysl-io-nonblock (~> 2.0)
81
+ rubysl-io-wait (~> 2.0)
82
+ rubysl-ipaddr (~> 2.0)
83
+ rubysl-irb (~> 2.1)
84
+ rubysl-logger (~> 2.0)
85
+ rubysl-mathn (~> 2.0)
86
+ rubysl-matrix (~> 2.0)
87
+ rubysl-mkmf (~> 2.0)
88
+ rubysl-monitor (~> 2.0)
89
+ rubysl-mutex_m (~> 2.0)
90
+ rubysl-net-ftp (~> 2.0)
91
+ rubysl-net-http (~> 2.0)
92
+ rubysl-net-imap (~> 2.0)
93
+ rubysl-net-pop (~> 2.0)
94
+ rubysl-net-protocol (~> 2.0)
95
+ rubysl-net-smtp (~> 2.0)
96
+ rubysl-net-telnet (~> 2.0)
97
+ rubysl-nkf (~> 2.0)
98
+ rubysl-observer (~> 2.0)
99
+ rubysl-open-uri (~> 2.0)
100
+ rubysl-open3 (~> 2.0)
101
+ rubysl-openssl (~> 2.0)
102
+ rubysl-optparse (~> 2.0)
103
+ rubysl-ostruct (~> 2.0)
104
+ rubysl-pathname (~> 2.0)
105
+ rubysl-prettyprint (~> 2.0)
106
+ rubysl-prime (~> 2.0)
107
+ rubysl-profile (~> 2.0)
108
+ rubysl-profiler (~> 2.0)
109
+ rubysl-pstore (~> 2.0)
110
+ rubysl-pty (~> 2.0)
111
+ rubysl-rational (~> 2.0)
112
+ rubysl-resolv (~> 2.0)
113
+ rubysl-rexml (~> 2.0)
114
+ rubysl-rinda (~> 2.0)
115
+ rubysl-rss (~> 2.0)
116
+ rubysl-scanf (~> 2.0)
117
+ rubysl-securerandom (~> 2.0)
118
+ rubysl-set (~> 2.0)
119
+ rubysl-shellwords (~> 2.0)
120
+ rubysl-singleton (~> 2.0)
121
+ rubysl-socket (~> 2.0)
122
+ rubysl-stringio (~> 2.0)
123
+ rubysl-strscan (~> 2.0)
124
+ rubysl-sync (~> 2.0)
125
+ rubysl-syslog (~> 2.0)
126
+ rubysl-tempfile (~> 2.0)
127
+ rubysl-thread (~> 2.0)
128
+ rubysl-thwait (~> 2.0)
129
+ rubysl-time (~> 2.0)
130
+ rubysl-timeout (~> 2.0)
131
+ rubysl-tmpdir (~> 2.0)
132
+ rubysl-tsort (~> 2.0)
133
+ rubysl-un (~> 2.0)
134
+ rubysl-uri (~> 2.0)
135
+ rubysl-weakref (~> 2.0)
136
+ rubysl-webrick (~> 2.0)
137
+ rubysl-xmlrpc (~> 2.0)
138
+ rubysl-yaml (~> 2.0)
139
+ rubysl-zlib (~> 2.0)
140
+ rubysl-abbrev (2.0.4)
141
+ rubysl-base64 (2.0.0)
142
+ rubysl-benchmark (2.0.1)
143
+ rubysl-bigdecimal (2.0.2)
144
+ rubysl-cgi (2.0.1)
145
+ rubysl-cgi-session (2.0.1)
146
+ rubysl-cmath (2.0.0)
147
+ rubysl-complex (2.0.0)
148
+ rubysl-continuation (2.0.0)
149
+ rubysl-coverage (2.0.3)
150
+ rubysl-csv (2.0.2)
151
+ rubysl-english (~> 2.0)
152
+ rubysl-curses (2.0.1)
153
+ rubysl-date (2.0.8)
154
+ rubysl-delegate (2.0.1)
155
+ rubysl-digest (2.0.3)
156
+ rubysl-drb (2.0.1)
157
+ rubysl-e2mmap (2.0.0)
158
+ rubysl-english (2.0.0)
159
+ rubysl-enumerator (2.0.0)
160
+ rubysl-erb (2.0.2)
161
+ rubysl-etc (2.0.3)
162
+ ffi2-generators (~> 0.1)
163
+ rubysl-expect (2.0.0)
164
+ rubysl-fcntl (2.0.4)
165
+ ffi2-generators (~> 0.1)
166
+ rubysl-fiber (2.0.0)
167
+ rubysl-fileutils (2.0.3)
168
+ rubysl-find (2.0.1)
169
+ rubysl-forwardable (2.0.1)
170
+ rubysl-getoptlong (2.0.0)
171
+ rubysl-gserver (2.0.0)
172
+ rubysl-socket (~> 2.0)
173
+ rubysl-thread (~> 2.0)
174
+ rubysl-io-console (2.0.0)
175
+ rubysl-io-nonblock (2.0.0)
176
+ rubysl-io-wait (2.0.0)
177
+ rubysl-ipaddr (2.0.0)
178
+ rubysl-irb (2.1.0)
179
+ rb-readline (~> 0.5)
180
+ rubysl-e2mmap (~> 2.0)
181
+ rubysl-mathn (~> 2.0)
182
+ rubysl-thread (~> 2.0)
183
+ rubysl-logger (2.1.0)
184
+ rubysl-mathn (2.0.0)
185
+ rubysl-matrix (2.1.0)
186
+ rubysl-e2mmap (~> 2.0)
187
+ rubysl-mkmf (2.0.1)
188
+ rubysl-fileutils (~> 2.0)
189
+ rubysl-shellwords (~> 2.0)
190
+ rubysl-monitor (2.0.0)
191
+ rubysl-mutex_m (2.0.0)
192
+ rubysl-net-ftp (2.0.1)
193
+ rubysl-net-http (2.0.4)
194
+ rubysl-cgi (~> 2.0)
195
+ rubysl-erb (~> 2.0)
196
+ rubysl-singleton (~> 2.0)
197
+ rubysl-net-imap (2.0.1)
198
+ rubysl-net-pop (2.0.1)
199
+ rubysl-net-protocol (2.0.1)
200
+ rubysl-net-smtp (2.0.1)
201
+ rubysl-net-telnet (2.0.0)
202
+ rubysl-nkf (2.0.1)
203
+ rubysl-observer (2.0.0)
204
+ rubysl-open-uri (2.0.0)
205
+ rubysl-open3 (2.0.0)
206
+ rubysl-openssl (2.2.1)
207
+ rubysl-optparse (2.0.1)
208
+ rubysl-shellwords (~> 2.0)
209
+ rubysl-ostruct (2.0.4)
210
+ rubysl-pathname (2.1.0)
211
+ rubysl-prettyprint (2.0.3)
212
+ rubysl-prime (2.0.1)
213
+ rubysl-profile (2.0.0)
214
+ rubysl-profiler (2.0.1)
215
+ rubysl-pstore (2.0.0)
216
+ rubysl-pty (2.0.3)
217
+ rubysl-rational (2.0.1)
218
+ rubysl-resolv (2.1.0)
219
+ rubysl-rexml (2.0.4)
220
+ rubysl-rinda (2.0.1)
221
+ rubysl-rss (2.0.0)
222
+ rubysl-scanf (2.0.0)
223
+ rubysl-securerandom (2.0.0)
224
+ rubysl-set (2.0.1)
225
+ rubysl-shellwords (2.0.0)
226
+ rubysl-singleton (2.0.0)
227
+ rubysl-socket (2.0.1)
228
+ rubysl-stringio (2.0.0)
229
+ rubysl-strscan (2.0.0)
230
+ rubysl-sync (2.0.0)
231
+ rubysl-syslog (2.1.0)
232
+ ffi2-generators (~> 0.1)
233
+ rubysl-tempfile (2.0.1)
234
+ rubysl-thread (2.0.2)
235
+ rubysl-thwait (2.0.0)
236
+ rubysl-time (2.0.3)
237
+ rubysl-timeout (2.0.0)
238
+ rubysl-tmpdir (2.0.1)
239
+ rubysl-tsort (2.0.1)
240
+ rubysl-un (2.0.0)
241
+ rubysl-fileutils (~> 2.0)
242
+ rubysl-optparse (~> 2.0)
243
+ rubysl-uri (2.0.0)
244
+ rubysl-weakref (2.0.0)
245
+ rubysl-webrick (2.0.0)
246
+ rubysl-xmlrpc (2.0.0)
247
+ rubysl-yaml (2.1.0)
248
+ rubysl-zlib (2.0.1)
48
249
  slop (3.6.0)
49
250
  sqlite3 (1.3.10)
50
251
  thread_safe (0.3.4)
@@ -52,11 +253,10 @@ GEM
52
253
  thread_safe (~> 0.1)
53
254
 
54
255
  PLATFORMS
55
- java
56
256
  ruby
57
257
 
58
258
  DEPENDENCIES
59
- database_cleaner (~> 1.3.0)
259
+ database_cleaner (~> 1.4.0)
60
260
  globalize!
61
261
  minitest
62
262
  minitest-reporters
@@ -0,0 +1,29 @@
1
+ require File.expand_path('../lib/globalize/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'globalize'
5
+ s.version = Globalize::Version
6
+ s.authors = ['Sven Fuchs', 'Joshua Harvey', 'Clemens Kofler', 'John-Paul Bader', 'Tomasz Stachewicz', 'Philip Arndt', 'Chris Salzberg']
7
+ s.email = 'nobody@globalize-rails.org'
8
+ s.homepage = 'http://github.com/globalize/globalize'
9
+ s.summary = 'Rails I18n de-facto standard library for ActiveRecord model/data translation'
10
+ s.description = "#{s.summary}."
11
+ s.license = "MIT"
12
+
13
+ s.files = Dir['{lib/**/*,[A-Z]*}']
14
+ s.platform = Gem::Platform::RUBY
15
+ s.require_path = 'lib'
16
+ s.rubyforge_project = '[none]'
17
+
18
+ s.add_dependency 'activerecord', '>= 4.2.0', '< 4.3'
19
+ s.add_dependency 'activemodel', '>= 4.2.0', '< 4.3'
20
+
21
+ s.add_development_dependency 'database_cleaner', '~> 1.4.0'
22
+ s.add_development_dependency 'minitest'
23
+ s.add_development_dependency 'minitest-reporters'
24
+
25
+ s.add_development_dependency 'sqlite3'
26
+ s.add_development_dependency 'rdoc'
27
+
28
+ s.add_development_dependency 'rake'
29
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'globalize'
@@ -2,6 +2,8 @@ require 'active_record'
2
2
  require 'patches/active_record/xml_attribute_serializer'
3
3
  require 'patches/active_record/query_method'
4
4
  require 'patches/active_record/uniqueness_validator'
5
+ require 'patches/active_record/persistence'
6
+
5
7
 
6
8
  module Globalize
7
9
  autoload :ActiveRecord, 'globalize/active_record'
@@ -51,11 +51,10 @@ module Globalize
51
51
  end
52
52
 
53
53
  def enable_serializable_attribute(attr_name)
54
- serializer = self.serialized_attributes[attr_name.to_s]
54
+ serializer = serializer_for_attribute(attr_name)
55
55
  if serializer.present?
56
56
  if defined?(::ActiveRecord::Coders::YAMLColumn) &&
57
- serializer.is_a?(::ActiveRecord::Coders::YAMLColumn)
58
-
57
+ serializer.is_a?(::ActiveRecord::Coders::YAMLColumn)
59
58
  serializer = serializer.object_class
60
59
  end
61
60
 
@@ -63,6 +62,13 @@ module Globalize
63
62
  end
64
63
  end
65
64
 
65
+ def serializer_for_attribute(attr_name)
66
+ column = self.columns_hash[attr_name.to_s]
67
+ if column && column.cast_type.is_a?(::ActiveRecord::Type::Serialized)
68
+ column.cast_type.coder
69
+ end
70
+ end
71
+
66
72
  def setup_translates!(options)
67
73
  apply_globalize_options(options)
68
74
 
@@ -37,7 +37,11 @@ module Globalize
37
37
  stash.reject {|locale, attrs| attrs.empty?}.each do |locale, attrs|
38
38
  translation = record.translations_by_locale[locale] ||
39
39
  record.translations.build(locale: locale.to_s)
40
- attrs.each { |name, value| translation[name] = value }
40
+
41
+ attrs.each do |name, value|
42
+ value = value.val if value.is_a?(Arel::Nodes::Casted)
43
+ translation[name] = value
44
+ end
41
45
  ensure_foreign_key_for(translation)
42
46
  translation.save!
43
47
  end
@@ -53,8 +57,7 @@ module Globalize
53
57
 
54
58
  # Sometimes the translation is initialised before a foreign key can be set.
55
59
  def ensure_foreign_key_for(translation)
56
- # AR >= 4.1 reflections renamed to _reflections
57
- translation[translation.class.reflections[:globalized_model].foreign_key] = record.id
60
+ translation[translation.class.reflections["globalized_model"].foreign_key] = record.id
58
61
  end
59
62
 
60
63
  def type_cast(name, value)
@@ -2,13 +2,13 @@ module Globalize
2
2
  module ActiveRecord
3
3
  module Exceptions
4
4
  class MigrationError < StandardError; end
5
-
5
+
6
6
  class BadFieldName < MigrationError
7
7
  def initialize(field)
8
8
  super("Missing translated field #{field.inspect}")
9
9
  end
10
10
  end
11
-
11
+
12
12
  class BadFieldType < MigrationError
13
13
  def initialize(name, type)
14
14
  super("Bad field type for field #{name.inspect} (#{type.inspect}), should be :string or :text")
@@ -30,12 +30,12 @@ module Globalize
30
30
  if attribute_changed?(name_str)
31
31
  # If there's already a change, delete it if this undoes the change.
32
32
  old = changed_attributes[name_str]
33
- changed_attributes.delete(name_str) if value == old
33
+ @changed_attributes.delete(name_str) if value == old
34
34
  else
35
35
  # If there's not a change yet, record it.
36
36
  old = globalize.fetch(options[:locale], name)
37
37
  old = old.dup if old.duplicable?
38
- changed_attributes[name_str] = old if value != old
38
+ @changed_attributes[name_str] = old if value != old
39
39
  end
40
40
 
41
41
  globalize.write(options[:locale], name, value)
@@ -93,7 +93,7 @@ module Globalize
93
93
 
94
94
  def reload(options = nil)
95
95
  translation_caches.clear
96
- translated_attribute_names.each { |name| @attributes.delete(name.to_s) }
96
+ translated_attribute_names.each { |name| @attributes.reset(name.to_s) }
97
97
  globalize.reset
98
98
  super(options)
99
99
  end
@@ -70,7 +70,7 @@ module Globalize
70
70
  connection.create_table(translations_table_name) do |t|
71
71
  t.references table_name.sub(/^#{table_name_prefix}/, '').singularize, :null => false
72
72
  t.string :locale, :null => false
73
- t.timestamps
73
+ t.timestamps :null => false
74
74
  end
75
75
  end
76
76
 
@@ -22,6 +22,14 @@ module Globalize
22
22
  end
23
23
  end
24
24
 
25
+ def order(opts, *rest)
26
+ if respond_to?(:translated_attribute_names) && parsed = parse_translated_order(opts)
27
+ super(parsed)
28
+ else
29
+ super
30
+ end
31
+ end
32
+
25
33
  def exists?(conditions = :none)
26
34
  if parsed = parse_translated_conditions(conditions)
27
35
  with_translations_in_fallbacks.exists?(parsed)
@@ -43,6 +51,7 @@ module Globalize
43
51
  end
44
52
 
45
53
  def where_values_hash(*args)
54
+ return super unless respond_to?(:translations_table_name)
46
55
  equalities = respond_to?(:with_default_scope) ? with_default_scope.where_values : where_values
47
56
  equalities = equalities.grep(Arel::Nodes::Equality).find_all { |node|
48
57
  node.left.relation.name == translations_table_name
@@ -52,7 +61,7 @@ module Globalize
52
61
 
53
62
  super.merge(Hash[equalities.map { |where|
54
63
  name = where.left.name
55
- [name, binds.fetch(name.to_s) { where.right }]
64
+ [name, binds.fetch(name.to_s) { right = where.right; right.is_a?(Arel::Nodes::Casted) ? right.val : right }]
56
65
  }])
57
66
  end
58
67
 
@@ -63,6 +72,27 @@ module Globalize
63
72
  relation.with_translations_in_fallbacks
64
73
  end
65
74
  end
75
+
76
+ private
77
+
78
+ def parse_translated_order(opts)
79
+ case opts
80
+ when Hash
81
+ ordering = opts.map do |column, direction|
82
+ klass = translated_column?(column) ? translation_class : self
83
+ klass.arel_table[column].send(direction)
84
+ end
85
+ order(ordering).order_values
86
+ when Symbol
87
+ translated_column_name(opts) if translated_attribute_names.include?(opts)
88
+ else # failsafe returns nothing
89
+ nil
90
+ end
91
+ end
92
+
93
+ def translated_column?(column)
94
+ translated_attribute_names.include?(column)
95
+ end
66
96
  end
67
97
  end
68
98
  end
@@ -1,3 +1,3 @@
1
1
  module Globalize
2
- Version = '4.0.3'
2
+ Version = '5.0.0'
3
3
  end
@@ -0,0 +1,26 @@
1
+ module ActiveRecord
2
+ module Persistence
3
+ # Updates the associated record with values matching those of the instance attributes.
4
+ # Returns the number of affected rows.
5
+ def _update_record(attribute_names = self.attribute_names)
6
+ attribute_names_without_translated = attribute_names.select{ |k| not respond_to?('translated?') or not translated?(k) }
7
+ attributes_values = arel_attributes_with_values_for_update(attribute_names_without_translated)
8
+ if attributes_values.empty?
9
+ 0
10
+ else
11
+ self.class.unscoped._update_record attributes_values, id, id_was
12
+ end
13
+ end
14
+
15
+ def _create_record(attribute_names = self.attribute_names)
16
+ attribute_names_without_translated = attribute_names.select{ |k| not respond_to?('translated?') or not translated?(k) }
17
+ attributes_values = arel_attributes_with_values_for_create(attribute_names_without_translated)
18
+
19
+ new_id = self.class.unscoped.insert attributes_values
20
+ self.id ||= new_id if self.class.primary_key
21
+
22
+ @new_record = false
23
+ id
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,338 @@
1
+ ![Globalize](http://globalize.github.io/globalize/images/globalize.png)
2
+
3
+ [![Build Status](https://travis-ci.org/globalize/globalize.svg?branch=master)](https://travis-ci.org/globalize/globalize) [![Code Climate](https://codeclimate.com/github/globalize/globalize.svg)](https://codeclimate.com/github/globalize/globalize)
4
+
5
+ You can chat with us using Gitter:
6
+
7
+ [![Gitter chat](https://badges.gitter.im/globalize/globalize.svg)](https://gitter.im/globalize/globalize)
8
+
9
+ Globalize builds on the [I18n API in Ruby on Rails](http://guides.rubyonrails.org/i18n.html)
10
+ to add model translations to ActiveRecord models.
11
+
12
+ ## Requirements
13
+
14
+ * ActiveRecord >= 4.2.0 (see below for installation with ActiveRecord 3.x)
15
+ * I18n
16
+
17
+ ## Installation
18
+
19
+ To install the ActiveRecord 4.2.x compatible version of Globalize with its default setup, just use:
20
+
21
+ ```ruby
22
+ gem install globalize
23
+ ```
24
+
25
+ When using bundler put this in your Gemfile:
26
+
27
+ ```ruby
28
+ gem 'globalize', '~> 5.0.0'
29
+ ```
30
+
31
+ To use the version of globalize for ActiveRecord 4.0 or 4.1, specify:
32
+
33
+ ```ruby
34
+ gem 'globalize', '~> 4.0.3'
35
+ ```
36
+
37
+ To use the version of globalize for ActiveRecord 3.1 or 3.2, specify:
38
+
39
+ ````ruby
40
+ gem 'globalize', '~> 3.1.0'
41
+ ````
42
+
43
+ (If you are using ActiveRecord 3.0, use version 3.0: `gem 'globalize', '3.0.4'`.)
44
+
45
+ The [`3-1-stable` branch](https://github.com/globalize/globalize/tree/3-1-stable) of this repository corresponds to the latest ActiveRecord 3 version of globalize. Note that `globalize3` has been deprecated and you are encouraged to update your Gemfile accordingly.
46
+
47
+ ## Model translations
48
+
49
+ Model translations allow you to translate your models' attribute values. E.g.
50
+
51
+ ```ruby
52
+ class Post < ActiveRecord::Base
53
+ translates :title, :text
54
+ end
55
+ ```
56
+
57
+ Allows you to translate the attributes :title and :text per locale:
58
+
59
+ ```ruby
60
+ I18n.locale = :en
61
+ post.title # => Globalize rocks!
62
+
63
+ I18n.locale = :he
64
+ post.title # => גלובאלייז2 שולט!
65
+ ```
66
+
67
+ In order to make this work, you'll need to add the appropriate translation tables.
68
+ Globalize comes with a handy helper method to help you do this.
69
+ It's called `create_translation_table!`. Here's an example:
70
+
71
+ Note that your migrations can use `create_translation_table!` and `drop_translation_table!`
72
+ only inside the `up` and `down` instance methods, respectively. You cannot use `create_translation_table!`
73
+ and `drop_translation_table!` inside the `change` instance method.
74
+
75
+ ### Creating translation tables
76
+
77
+ ***Do not use the `change` method, use `up` and `down`!***
78
+
79
+ ```ruby
80
+ class CreatePosts < ActiveRecord::Migration
81
+ def up
82
+ create_table :posts do |t|
83
+ t.timestamps
84
+ end
85
+ Post.create_translation_table! :title => :string, :text => :text
86
+ end
87
+ def down
88
+ drop_table :posts
89
+ Post.drop_translation_table!
90
+ end
91
+ end
92
+ ```
93
+
94
+ Also, you can pass options for specific columns. Here’s an example:
95
+
96
+ ```ruby
97
+ class CreatePosts < ActiveRecord::Migration
98
+ def up
99
+ create_table :posts do |t|
100
+ t.timestamps
101
+ end
102
+ Post.create_translation_table! :title => :string,
103
+ :text => {:type => :text, :null => false, :default => 'abc'}
104
+ end
105
+ def down
106
+ drop_table :posts
107
+ Post.drop_translation_table!
108
+ end
109
+ end
110
+ ```
111
+
112
+ Note that the ActiveRecord model `Post` must already exist and have a `translates`
113
+ directive listing the translated fields.
114
+
115
+ ## Migrating existing data to and from the translated version
116
+
117
+ As well as creating a translation table, you can also use `create_translation_table!`
118
+ to migrate across any existing data to the default locale. This can also operate
119
+ in reverse to restore any translations from the default locale back to the model
120
+ when you don't want to use a translation table anymore using `drop_translation_table!`
121
+
122
+ This feature makes use of `untranslated_attributes` which allows access to the
123
+ model's attributes as they were before the translation was applied. Here's an
124
+ example (which assumes you already have a model called `Post` and its table
125
+ exists):
126
+
127
+ ```ruby
128
+ class TranslatePosts < ActiveRecord::Migration
129
+ def self.up
130
+ Post.create_translation_table!({
131
+ :title => :string,
132
+ :text => :text
133
+ }, {
134
+ :migrate_data => true
135
+ })
136
+ end
137
+
138
+ def self.down
139
+ Post.drop_translation_table! :migrate_data => true
140
+ end
141
+ end
142
+ ```
143
+
144
+ NOTE: Make sure you drop the translated columns from the parent table after all your data is safely migrated.
145
+
146
+ ## Adding additional fields to the translation table
147
+
148
+ In order to add a new field to an existing translation table, you can use `add_translation_fields!`:
149
+
150
+ ```ruby
151
+ class AddAuthorToPost < ActiveRecord::Migration
152
+ def up
153
+ Post.add_translation_fields! author: :text
154
+ end
155
+
156
+ def down
157
+ remove_column :post_translations, :author
158
+ end
159
+ end
160
+ ```
161
+
162
+ NOTE: Remember to add the new field to the model:
163
+
164
+ ```ruby
165
+ translates :title, :author
166
+ ```
167
+
168
+ ## Versioning with Globalize
169
+
170
+ See the [globalize-versioning](https://github.com/globalize/globalize-versioning) gem.
171
+
172
+ ## I18n fallbacks for empty translations
173
+
174
+ It is possible to enable fallbacks for empty translations. It will depend on the
175
+ configuration setting you have set for I18n translations in your Rails config.
176
+
177
+ You can enable them by adding the next line to `config/application.rb` (or only
178
+ `config/environments/production.rb` if you only want them in production)
179
+
180
+ ```ruby
181
+ config.i18n.fallbacks = true
182
+ ```
183
+
184
+ By default, globalize will only use fallbacks when your translation model does
185
+ not exist or the translation value for the item you've requested is `nil`.
186
+ However it is possible to also use fallbacks for `blank` translations by adding
187
+ `:fallbacks_for_empty_translations => true` to the `translates` method.
188
+
189
+ ```ruby
190
+ class Post < ActiveRecord::Base
191
+ translates :title, :name
192
+ end
193
+
194
+ puts post.translations.inspect
195
+ # => [#<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
196
+ #<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>]
197
+
198
+ I18n.locale = :en
199
+ post.title # => 'Globalize rocks!'
200
+ post.name # => 'Globalize'
201
+
202
+ I18n.locale = :nl
203
+ post.title # => ''
204
+ post.name # => 'Globalize'
205
+ ```
206
+
207
+ ```ruby
208
+ class Post < ActiveRecord::Base
209
+ translates :title, :name, :fallbacks_for_empty_translations => true
210
+ end
211
+
212
+ puts post.translations.inspect
213
+ # => [#<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
214
+ #<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>]
215
+
216
+ I18n.locale = :en
217
+ post.title # => 'Globalize rocks!'
218
+ post.name # => 'Globalize'
219
+
220
+ I18n.locale = :nl
221
+ post.title # => 'Globalize rocks!'
222
+ post.name # => 'Globalize'
223
+ ```
224
+
225
+ ## Fallback locales to each other
226
+
227
+ It is possible to setup locales to fallback to each other.
228
+
229
+ ```ruby
230
+ class Post < ActiveRecord::Base
231
+ translates :title, :name
232
+ end
233
+
234
+ Globalize.fallbacks = {:en => [:en, :pl], :pl => [:pl, :en]}
235
+
236
+ I18n.locale = :en
237
+ en_post = Post.create(:title => 'en_title')
238
+
239
+ I18n.locale = :pl
240
+ pl_post = Post.create(:title => 'pl_title')
241
+ en_post.title # => 'en_title'
242
+
243
+ I18n.locale = :en
244
+ en_post.title # => 'en_title'
245
+ pl_post.title # => 'pl_title'
246
+ ```
247
+
248
+
249
+ ## Scoping objects by those with translations
250
+
251
+ To only return objects that have a translation for the given locale we can use
252
+ the `with_translations` scope. This will only return records that have a
253
+ translations for the passed in locale.
254
+
255
+ ```ruby
256
+ Post.with_translations('en')
257
+ # => [
258
+ #<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
259
+ #<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>
260
+ ]
261
+
262
+ Post.with_translations(I18n.locale)
263
+ # => [
264
+ #<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
265
+ #<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>
266
+ ]
267
+
268
+ Post.with_translations('de')
269
+ # => []
270
+ ```
271
+
272
+ ## Show different languages
273
+
274
+ In views, if there is content from different locales that you wish to display,
275
+ you should use the `with_locale` option with a block, as below:
276
+
277
+ ```erb
278
+ <% Globalize.with_locale(:en) do %>
279
+ <%= render "my_translated_partial" %>
280
+ <% end %>
281
+ ```
282
+
283
+ Your partial will now be rendered with the `:en` locale set as the current locale.
284
+
285
+ ## Interpolation
286
+
287
+ Globalize supports interpolation in a similar manner to I18n.
288
+
289
+ ```ruby
290
+ class Post < ActiveRecord::Base
291
+ translates :title
292
+ end
293
+
294
+ I18n.locale = :en
295
+ post.title = "Globalize %{superlative}!"
296
+
297
+ post.title
298
+ # #=> "Globalize %{superlative}!"
299
+
300
+ post.title(:foo => "bar")
301
+ # SomeError: missing interpolation argument :superlative
302
+
303
+ post.title(:superlative => "rocks")
304
+ # #=> "Globalize rocks!"
305
+ ```
306
+
307
+ ## Fragment caching
308
+
309
+ Don't forget to add globalize locale into the `cache_key` to separate different localizations of the record.
310
+ One of the possible ways to implement it:
311
+
312
+ ```ruby
313
+ # inside translated model
314
+ def cache_key
315
+ super + '-' + Globalize.locale.to_s
316
+ end
317
+ ```
318
+
319
+ ## Official Globalize extensions
320
+
321
+ * [globalize-accessors](https://github.com/globalize/globalize-accessors) - Replacement for [easy_globalize_3_accessors](https://github.com/paneq/easy_globalize3_accessors) compatible with Globalize 3.x and 4.x.
322
+ * [globalize-versioning](https://github.com/globalize/globalize-versioning) - Versioning support for using Globalize with [`paper_trail`](https://github.com/airblade/paper_trail).
323
+
324
+ ## Alternative Solutions
325
+
326
+ * [Veger's fork](http://github.com/veger/globalize2) - uses default AR schema for the default locale, delegates to the translations table for other locales only
327
+ * [TranslatableColumns](http://github.com/iain/translatable_columns) - have multiple languages of the same attribute in a model (Iain Hecker)
328
+ * [Traco](https://github.com/barsoom/traco) - A newer take on using multiple columns in the same model (Barsoom)
329
+ * [localized_record](http://github.com/glennpow/localized_record) - allows records to have localized attributes without any modifications to the database (Glenn Powell)
330
+ * [model_translations](http://github.com/janne/model_translations) - Minimal implementation of Globalize2 style model translations (Jan Andersson)
331
+ * [hstore_translate](http://github.com/robworley/hstore_translate) - Rails I18n library for ActiveRecord model/data translation using PostgreSQL's hstore datatype (Rob Worley)
332
+
333
+ ## Related solutions
334
+
335
+ * [globalize2_versioning](http://github.com/joshmh/globalize2_versioning) - acts_as_versioned style versioning for globalize2 (Joshua Harvey)
336
+ * [i18n_multi_locales_validations](http://github.com/ZenCocoon/i18n_multi_locales_validations) - multi-locales attributes validations to validates attributes from globalize2 translations models (Sébastien Grosjean)
337
+ * [migrate_from_globalize1](http://gist.github.com/120867) - migrate model translations from Globalize1 to globalize2 (Tomasz Stachewicz)
338
+ * [batch_translations](http://github.com/rilla/batch_translations) - allow saving multiple globalize2 translations in the same request (Jose Alvarez Rilla)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: globalize
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.3
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2014-11-25 00:00:00.000000000 Z
17
+ date: 2015-02-03 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: activerecord
@@ -22,54 +22,54 @@ dependencies:
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 4.0.0
25
+ version: 4.2.0
26
26
  - - "<"
27
27
  - !ruby/object:Gem::Version
28
- version: '5'
28
+ version: '4.3'
29
29
  type: :runtime
30
30
  prerelease: false
31
31
  version_requirements: !ruby/object:Gem::Requirement
32
32
  requirements:
33
33
  - - ">="
34
34
  - !ruby/object:Gem::Version
35
- version: 4.0.0
35
+ version: 4.2.0
36
36
  - - "<"
37
37
  - !ruby/object:Gem::Version
38
- version: '5'
38
+ version: '4.3'
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: activemodel
41
41
  requirement: !ruby/object:Gem::Requirement
42
42
  requirements:
43
43
  - - ">="
44
44
  - !ruby/object:Gem::Version
45
- version: 4.0.0
45
+ version: 4.2.0
46
46
  - - "<"
47
47
  - !ruby/object:Gem::Version
48
- version: '5'
48
+ version: '4.3'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
- version: 4.0.0
55
+ version: 4.2.0
56
56
  - - "<"
57
57
  - !ruby/object:Gem::Version
58
- version: '5'
58
+ version: '4.3'
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: database_cleaner
61
61
  requirement: !ruby/object:Gem::Requirement
62
62
  requirements:
63
63
  - - "~>"
64
64
  - !ruby/object:Gem::Version
65
- version: 1.3.0
65
+ version: 1.4.0
66
66
  type: :development
67
67
  prerelease: false
68
68
  version_requirements: !ruby/object:Gem::Requirement
69
69
  requirements:
70
70
  - - "~>"
71
71
  - !ruby/object:Gem::Version
72
- version: 1.3.0
72
+ version: 1.4.0
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: minitest
75
75
  requirement: !ruby/object:Gem::Requirement
@@ -152,6 +152,8 @@ files:
152
152
  - Gemfile.lock
153
153
  - LICENSE
154
154
  - Rakefile
155
+ - globalize.gemspec
156
+ - init.rb
155
157
  - lib/globalize.rb
156
158
  - lib/globalize/active_record.rb
157
159
  - lib/globalize/active_record/act_macro.rb
@@ -167,26 +169,16 @@ files:
167
169
  - lib/globalize/version.rb
168
170
  - lib/i18n/missing_translations_log_handler.rb
169
171
  - lib/i18n/missing_translations_raise_handler.rb
172
+ - lib/patches/active_record/persistence.rb
170
173
  - lib/patches/active_record/query_method.rb
171
174
  - lib/patches/active_record/uniqueness_validator.rb
172
175
  - lib/patches/active_record/xml_attribute_serializer.rb
176
+ - readme.md
173
177
  homepage: http://github.com/globalize/globalize
174
178
  licenses:
175
179
  - MIT
176
180
  metadata: {}
177
- post_install_message: |2+
178
-
179
- Globalize has extracted versioning support to a separate gem named
180
- globalize-versioning. If you are using versioning (with paper_trail
181
- or any other versioning gem), please add the line
182
- "gem 'globalize-versioning'" to your Gemfile and go to the github
183
- page at globalize/globalize-versioning if you encounter any problems.
184
-
185
- Note that the globalize-versioning gem does not delegate versions to
186
- the translation table, so you will have to update your syntax to
187
- the form: `post.translation.versions`. See the globalize-versioning
188
- readme for details.
189
-
181
+ post_install_message:
190
182
  rdoc_options: []
191
183
  require_paths:
192
184
  - lib
@@ -202,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
194
  version: '0'
203
195
  requirements: []
204
196
  rubyforge_project: "[none]"
205
- rubygems_version: 2.2.2
197
+ rubygems_version: 2.4.5
206
198
  signing_key:
207
199
  specification_version: 4
208
200
  summary: Rails I18n de-facto standard library for ActiveRecord model/data translation