globalize-rails5 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +111 -0
  3. data/CONTRIBUTING.md +37 -0
  4. data/Gemfile +26 -0
  5. data/LICENSE +22 -0
  6. data/README.md +430 -0
  7. data/Rakefile +55 -0
  8. data/lib/globalize.rb +90 -0
  9. data/lib/globalize/active_record.rb +14 -0
  10. data/lib/globalize/active_record/act_macro.rb +111 -0
  11. data/lib/globalize/active_record/adapter.rb +99 -0
  12. data/lib/globalize/active_record/adapter_dirty.rb +54 -0
  13. data/lib/globalize/active_record/attributes.rb +26 -0
  14. data/lib/globalize/active_record/class_methods.rb +124 -0
  15. data/lib/globalize/active_record/exceptions.rb +13 -0
  16. data/lib/globalize/active_record/instance_methods.rb +218 -0
  17. data/lib/globalize/active_record/migration.rb +210 -0
  18. data/lib/globalize/active_record/query_methods.rb +98 -0
  19. data/lib/globalize/active_record/translation.rb +45 -0
  20. data/lib/globalize/interpolation.rb +28 -0
  21. data/lib/globalize/version.rb +3 -0
  22. data/lib/i18n/missing_translations_log_handler.rb +41 -0
  23. data/lib/i18n/missing_translations_raise_handler.rb +25 -0
  24. data/lib/patches/active_record/persistence.rb +17 -0
  25. data/lib/patches/active_record/query_method.rb +3 -0
  26. data/lib/patches/active_record/rails4/query_method.rb +35 -0
  27. data/lib/patches/active_record/rails4/uniqueness_validator.rb +42 -0
  28. data/lib/patches/active_record/rails5/uniqueness_validator.rb +47 -0
  29. data/lib/patches/active_record/relation.rb +12 -0
  30. data/lib/patches/active_record/serialization.rb +21 -0
  31. data/lib/patches/active_record/uniqueness_validator.rb +5 -0
  32. data/lib/patches/active_record/xml_attribute_serializer.rb +23 -0
  33. metadata +204 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8035672fdd06c82bda9ba24e06d99bba2b7452df
4
+ data.tar.gz: 2e1fc5af6825c8f5f948d6a37f830cd0e6576741
5
+ SHA512:
6
+ metadata.gz: 7443b9adaa38622b549919ad414ade86b5a2f19f925191dbbf56555e0da03173949121a9d5d89bb18313e9260f2451a32c4cd8f26a7a95ba83a2887e8f4947ff
7
+ data.tar.gz: 3da06df9e8a4c606840713c04fc279b140745b43c5d3408d94440a184f0f2f904d2c45c1d148eff43afedd9f8c8d9015398d64db4f8d8c52bd6f64e212ecc74b
@@ -0,0 +1,111 @@
1
+ # Globalize Changelog
2
+
3
+ ## 5.1.0 (unreleased)
4
+
5
+ * Replaced `after_` callbacks with `before_` callbacks and set `autosave: true` by default. [#341](https://github.com/globalize/globalize/pull/341) by [Andrew Volozhanin](https://github.com/scarfacedeb)
6
+ * Add [RequestStore](https://github.com/steveklabnik/request_store) to make Globalize thread-safe again [#420](https://github.com/globalize/globalize/pull/420)
7
+ * Join the translations table when ordering by translated attributes (https://github.com/globalize/globalize/pull/447). (thanks [Thomas Maas](https://github.com/thomasmaas) & [Michal Cichra](https://github.com/mikz)).
8
+ * Add `unique` to `with_translation` to prevent duplicates if fallbacks are defined and the queried locale is not the fallback language. [#489](https://github.com/globalize/globalize/pull/489) by [krisdigital](https://github.com/krisdigital)
9
+
10
+ ## 5.0.1 (2015-02-15)
11
+
12
+ * Don't touch table when model is loaded. [#412](https://github.com/globalize/globalize/pull/412)
13
+ * Remove handling for locale attribute on parent model [#411](https://github.com/globalize/globalize/pull/411) by awesome [Tekin Suleyman](https://github.com/tekin).
14
+
15
+ ## 5.0.0 (2015-02-03)
16
+ * 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).
17
+
18
+ ## 4.0.3 (2014-11-24)
19
+ * 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).
20
+ * 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).
21
+ * Removed all usages of `Thread.local`. [#374](https://github.com/globalize/globalize/pull/374). (thanks [Hubert Lee](https://github.com/hube)).
22
+ * Added `available_locales` method. This duplicates `translated_locales` method, but it doesn't use a separate `DISTINCT` query. [#339](https://github.com/globalize/globalize/pull/339). (thanks [Andrew Volozhanin](https://github.com/scarfacedeb)).
23
+
24
+ ## 4.0.2 (2014-06-29)
25
+ * Use `reflections` class method so `ensure_foreign_key_for` works in AR >= 4.1.2, fixes [#353](https://github.com/globalize/globalize/pull/353).
26
+ * Set `touch:true` on `belongs_to` for the globalized model, fixes [#330](https://github.com/globalize/globalize/pull/330) (thanks [shlensky](https://github.com/shlensky)).
27
+ * Accept optional arguments passed to `where_values_hash`, fixes [#354](https://github.com/globalize/globalize/pull/354) (thanks [felixbuenemann](https://github.com/felixbuenemann)).
28
+
29
+ ## 4.0.1 (2014-03-29)
30
+ * Fix bug where `with_translations` only works if called after `where` in relation chain, fixes [#343](https://github.com/globalize/globalize/issues/343).
31
+ * Use `preload` and `joins` instead of `includes` in `with_translations`, fixes [#329](https://github.com/globalize/globalize/issues/329) (thanks [Andrew Volozhanin](https://github.com/scarfacedeb)).
32
+ * Update `database_cleaner` dependency to 1.2.0.
33
+ * Support use of `first`/`take`/`last` with limit on queries with translated attributes, fixes [#322](https://github.com/globalize/globalize/issues/322) (thanks [prusswan](https://github.com/prusswan)).
34
+ * Ensure that options are always extracted from `attr_names` in `Globalize::ActiveRecord::ActMacro#translates`, PR [#319](https://github.com/globalize/globalize/pull/319) (thanks [Marek](https://github.com/keram)).
35
+
36
+ ## 4.0.0 (2014-01-04)
37
+ * Extract all versioning-related code to separate [globalize-versioning](https://github.com/globalize/globalize-versioning) gem.
38
+
39
+ ## 4.0.0.alpha.5 (2014-01-04)
40
+ * Fix issue where globalize breaks has_many through when model called with `where` (thanks [Paul McMahon](https://github.com/pwim)).
41
+ * Modify dup so that translations are copied, and remove custom clone code to conform to Rails/AR semantics (thanks [Paul McMahon](https://github.com/pwim)).
42
+
43
+ ## 4.0.0.alpha.4 (2013-12-30)
44
+ * Add this changelog.
45
+ * Add contributing guidelines.
46
+ * Group options into more structured methods in act_macro.rb.
47
+ * Remove dynamic finder code from globalize3, no longer used in AR4.
48
+ * Get hash of translated attributes by calling attribute on model, not translation.
49
+ * Define translation readers/writers in separate methods.
50
+ * Test against AR 4.1 and AR 4.0.
51
+ * Switch to minitest-reporters for colouring output from minitest.
52
+ * Remove find_or_instantiator_by_attributes which is no longer used in AR4.
53
+ * Set I18n.available_locales in tests to avoid deprecation message.
54
+ * Reorganize specs into describe blocks to clarify object of specs.
55
+
56
+ ## 4.0.0.alpha.3 (2013-12-18)
57
+
58
+ * Move ActiveRecord::Relation#where_values_hash patch into globalize relation class to avoid monkeypatching.
59
+ * Add Code Climate Score (thanks [BrandonMathis](https://github.com/BrandonMathis)).
60
+ * Query using Globalize.fallbacks rather than locale only when fetching a record (thanks [@huoxito](https://github.com/huoxito)).
61
+ * Use a module (QueryMethods) rather than a class for overriding functionality of ActiveRecord::Relation.
62
+ * Use ActiveRecord::Relation#extending! to extend ActiveRecord::Base#relation with QueryMethods, works with associations as well.
63
+
64
+ ## 4.0.0.alpha.2 (2013-10-24)
65
+
66
+ * Add license to gemspec.
67
+ * Update references to ActiveRecord 3 -> ActiveRecord.
68
+ * Replace references to globalize3 with globalize and remove references to ActiveRecord 3.x.
69
+ * Document `3-0-stable` branch in readme.
70
+ * Convert test syntax to MiniTest::Spec.
71
+ * Extract easy accessors functionality, moved to new [globalize-accessors](https://github.com/globalize/globalize-accessors) gem.
72
+ * Check that `first` is not nil before reloading translations, fixes [#282](https://github.com/globalize/globalize/issues/282).
73
+ * Duplicate arguments in query finders before modifying them, fixes [#284](https://github.com/globalize/globalize/issues/284).
74
+ * Add test for `find_or_create_by` with translated attribute.
75
+
76
+ ## 4.0.0.alpha.1 (2013-10-09)
77
+
78
+ * Initial release of Rails 4-compatible gem.
79
+
80
+ ## 3.1.0 (2014-01-25)
81
+
82
+ * Backport scope support on uniqueness validation from 4.0, drop support for ActiveRecord < 3.1, fixes [#324](https://github.com/globalize/globalize/issues/324).
83
+
84
+ ## 3.0.5 (2015-04-24)
85
+
86
+ * Now working properly with the squeel library. (thanks [Toru Mori](https://github.com/torumori)). See [#437](https://github.com/globalize/globalize/pull/437)
87
+
88
+ ## 3.0.4 (2014-01-08)
89
+
90
+ * Extract all versioning-related code to separate [globalize-versioning](https://github.com/globalize/globalize-versioning) gem.
91
+
92
+ ## 3.0.3 (2013-12-26)
93
+
94
+ * Ensure that foreign key is always set when saving translations (thanks [Andrew Feng](https://github.com/mingliangfeng)).
95
+ * Patch I18n to add back I18n.interpolate after it was removed (accidentally?) in v0.5.2 (see [svenfuchs/i18n#232](https://github.com/svenfuchs/i18n/issues/232). Hopefully this patch will be temporary.
96
+ * Explicitly test compatibility with FriendlyId to avoid issues like [#306](https://github.com/globalize/globalize/issues/306).
97
+ * Only override ActiveRecord::Base#relation to patch where_values_hash if using AR >= 3.2.1.
98
+
99
+ ## 3.0.2 (2013-12-07)
100
+
101
+ * Alias `ActiveRecord::Base#relation` and include query method overrides as module, fixes [#306](https://github.com/globalize/globalize/issues/306) and [norman/friendly_id#485](https://github.com/norman/friendly_id/issues/485).
102
+
103
+ ## 3.0.1 (2013-11-07)
104
+
105
+ * Move `ActiveRecord::Relation#where_values_hash` patch to Globalize-specific Relation class that inherits from `ActiveRecord::Relation` to fix compatibility issue with Squeel ([#288](https://github.com/globalize/globalize/issues/288)).
106
+ * Use FriendlyId pattern for overriding `ActiveRecord::Base#relation` to avoid conflict.
107
+ * Remove `:null => false` condition on reference to parent model in translation table migration, partial fix for [refinery/refinerycms#2450](https://github.com/refinery/refinerycms/issues/2450).
108
+
109
+ ## 3.0.0 (2013-10-24)
110
+
111
+ * Initial release with new version numbering.
@@ -0,0 +1,37 @@
1
+ # Contributing to Globalize
2
+
3
+ Globalize is a community project, and would not be here today if it were not for the support of the community of [contributors](https://github.com/globalize/globalize/graphs/contributors) that have kept it alive and running. Thank you for your support!
4
+
5
+ ## Bugs
6
+
7
+ If you find a bug or something is not working as expected, please search through the [github issues](https://github.com/globalize/globalize/issues) and on [stackoverflow](http://stackoverflow.com/questions/tagged/globalize) first. If you cannot find any answers related to your issue, post a new one and we will try to address it as soon as we can. Note that we prioritize Rails 4 issues (`master` branch) over Rails 3 issues (`3-0-stable` branch).
8
+
9
+ If you also have some idea how to fix the bug, then by all means post a pull request (see below).
10
+
11
+ ## Features
12
+
13
+ Have an idea for a new feature? Great! Keep in mind though that we are trying to cut down on non-core functionality in the Globalize core and push it to separate extensions, such as [globalize-accessors](https://github.com/globalize/globalize-accessors). If you are proposing something like this, we would prefer you to create a separate repository and gem for it.
14
+
15
+ If however your feature would improve the core functionality of Globalize, please do submit a PR, preferably to the `master` branch.
16
+
17
+ ## Refactoring
18
+
19
+ Have some free time? Help us improve our [code climate score](https://codeclimate.com/github/globalize/globalize) by refactoring the codebase. If the tests still pass and the changes seem reasonable, we will happily merge them. As elsewhere, priority always goes to the Rails/AR 4 series (`master` branch).
20
+
21
+ ## Documentation
22
+
23
+ Globalize needs better documentation. That includes more inline comments explaining clearly what code is doing, as well as reference documentation beyond the [readme](readme.md) -- possibly in the github wiki. Please contact us if you would like to help with documentation.
24
+
25
+ ## Pull Requests
26
+
27
+ Have a bug fix, code improvement or proposed feature? Do the following:
28
+
29
+ 1. Fork the repository.
30
+ 2. Create your feature branch: `git checkout -b my_new_feature`
31
+ 3. Commit your changes: `git commit -am 'Add some new feature'`
32
+ 4. Push to the branch: `git push origin my_new_feature`
33
+ 5. Submit a pull request.
34
+
35
+ For pull requests to Rails/ActiveRecord 4 version of Globalize (v3.x), post to the `master` branch. For pull requests to the Rails/ActiveRecord 3.x version of Globalize (3.x), post to the `3-0-stable` branch.
36
+
37
+ When you submit the pull request, Travis CI will run the [test suite](https://travis-ci.org/globalize/globalize) against your branch and will highlight any failures. Unless there is a good reason for it, we do not generally accept pull requests that take Globalize from green to red.
data/Gemfile ADDED
@@ -0,0 +1,26 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "pry"
6
+
7
+ eval File.read(File.expand_path("../gemfiles/.gemfile.database-config.rb", __FILE__))
8
+
9
+ platforms :rbx do
10
+ gem "rubysl", "~> 2.0"
11
+ gem "rubinius-developer_tools"
12
+ end
13
+
14
+ platforms :jruby do
15
+ if !ENV['TRAVIS'] || ENV['DB'] == 'sqlite3'
16
+ gem 'activerecord-jdbcsqlite3-adapter', git: "https://github.com/jruby/activerecord-jdbc-adapter"
17
+ end
18
+
19
+ if !ENV['TRAVIS'] || ENV['DB'] == 'mysql'
20
+ gem 'activerecord-jdbcmysql-adapter', git: "https://github.com/jruby/activerecord-jdbc-adapter"
21
+ end
22
+
23
+ if !ENV['TRAVIS'] || %w(postgres postgresql).include?(ENV['DB'])
24
+ gem 'activerecord-jdbcpostgresql-adapter', git: "https://github.com/jruby/activerecord-jdbc-adapter"
25
+ end
26
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2008-2014 Sven Fuchs, Joshua Harvey, Clemens Kofler, John-Paul
4
+ Bader, Tomasz Stachewicz, Philip Arndt, Chris Salzberg
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
@@ -0,0 +1,430 @@
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
+ In other words, a way to translate actual user-generated content, for example; a single blog post with multiple translations.
13
+
14
+ ## Requirements
15
+
16
+ * ActiveRecord >= 4.2.0 (see below for installation with ActiveRecord 3.x)
17
+ * I18n
18
+
19
+ ## Installation
20
+
21
+ To install the ActiveRecord 4.2.x compatible version of Globalize with its default setup, just use:
22
+
23
+ ```ruby
24
+ gem install globalize
25
+ ```
26
+
27
+ When using bundler put this in your Gemfile:
28
+
29
+ ```ruby
30
+ gem 'globalize', '~> 5.0.0'
31
+ ```
32
+
33
+ You have to use branch **master** to work with Rails 5.
34
+
35
+ Put in your Gemfile
36
+
37
+ ```ruby
38
+ gem 'globalize', git: 'https://github.com/globalize/globalize'
39
+ gem 'activemodel-serializers-xml'
40
+ ```
41
+
42
+ To use the version of globalize for ActiveRecord 4.0 or 4.1, specify:
43
+
44
+ ```ruby
45
+ gem 'globalize', '~> 4.0.3'
46
+ ```
47
+
48
+ To use the version of globalize for ActiveRecord 3.1 or 3.2, specify:
49
+
50
+ ````ruby
51
+ gem 'globalize', '~> 3.1.0'
52
+ ````
53
+
54
+ (If you are using ActiveRecord 3.0, use version 3.0: `gem 'globalize', '3.0.4'`.)
55
+
56
+ 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.
57
+
58
+ ## Model translations
59
+
60
+ Model translations allow you to translate your models' attribute values. E.g.
61
+
62
+ ```ruby
63
+ class Post < ActiveRecord::Base
64
+ translates :title, :text
65
+ end
66
+ ```
67
+
68
+ Allows you to translate the attributes :title and :text per locale:
69
+
70
+ ```ruby
71
+ I18n.locale = :en
72
+ post.title # => Globalize rocks!
73
+
74
+ I18n.locale = :he
75
+ post.title # => גלובאלייז2 שולט!
76
+ ```
77
+
78
+ You can also set translations with mass-assignment by specifying the locale:
79
+
80
+ ```ruby
81
+ post.attributes = { title: 'גלובאלייז2 שולט!', locale: :he }
82
+ ```
83
+
84
+ In order to make this work, you'll need to add the appropriate translation tables.
85
+ Globalize comes with a handy helper method to help you do this.
86
+ It's called `create_translation_table!`. Here's an example:
87
+
88
+ Note that your migrations can use `create_translation_table!` and `drop_translation_table!`
89
+ only inside the `up` and `down` instance methods, respectively. You cannot use `create_translation_table!`
90
+ and `drop_translation_table!` inside the `change` instance method.
91
+
92
+ ### Creating translation tables
93
+
94
+ Also note that before you can create a translation table, you have to define the translated attributes via `translates` in your model as shown above.
95
+
96
+ ```ruby
97
+ class CreatePosts < ActiveRecord::Migration
98
+ def change
99
+ create_table :posts do |t|
100
+ t.timestamps
101
+ end
102
+
103
+ reversible do |dir|
104
+ dir.up do
105
+ Post.create_translation_table! :title => :string, :text => :text
106
+ end
107
+
108
+ dir.down do
109
+ Post.drop_translation_table!
110
+ end
111
+ end
112
+ end
113
+ end
114
+ ```
115
+
116
+ Also, you can pass options for specific columns. Here’s an example:
117
+
118
+ ```ruby
119
+ class CreatePosts < ActiveRecord::Migration
120
+ def change
121
+ create_table :posts do |t|
122
+ t.timestamps
123
+ end
124
+
125
+ reversible do |dir|
126
+ dir.up do
127
+ Post.create_translation_table! :title => :string,
128
+ :text => {:type => :text, :null => false, :default => 'abc'}
129
+ end
130
+
131
+ dir.down do
132
+ Post.drop_translation_table!
133
+ end
134
+ end
135
+ end
136
+ end
137
+ ```
138
+
139
+ Note that the ActiveRecord model `Post` must already exist and have a `translates`
140
+ directive listing the translated fields.
141
+
142
+ ## Migrating existing data to and from the translated version
143
+
144
+ As well as creating a translation table, you can also use `create_translation_table!`
145
+ to migrate across any existing data to the default locale. This can also operate
146
+ in reverse to restore any translations from the default locale back to the model
147
+ when you don't want to use a translation table anymore using `drop_translation_table!`
148
+
149
+ This feature makes use of `untranslated_attributes` which allows access to the
150
+ model's attributes as they were before the translation was applied. Here's an
151
+ example (which assumes you already have a model called `Post` and its table
152
+ exists):
153
+
154
+ ```ruby
155
+ class TranslatePosts < ActiveRecord::Migration
156
+ def change
157
+ reversible do |dir|
158
+ dir.up do
159
+ Post.create_translation_table!({
160
+ :title => :string,
161
+ :text => :text
162
+ }, {
163
+ :migrate_data => true
164
+ })
165
+ end
166
+
167
+ dir.down do
168
+ Post.drop_translation_table! :migrate_data => true
169
+ end
170
+ end
171
+ end
172
+ end
173
+ ```
174
+
175
+ NOTE: Make sure you drop the translated columns from the parent table after all your data is safely migrated.
176
+
177
+ To automatically remove the translated columns from the parent table after the data migration, please use option `remove_source_columns`.
178
+
179
+ ```ruby
180
+ class TranslatePosts < ActiveRecord::Migration
181
+ def self.up
182
+ Post.create_translation_table!({
183
+ :title => :string,
184
+ :text => :text
185
+ }, {
186
+ :migrate_data => true,
187
+ :remove_source_columns => true
188
+ })
189
+ end
190
+
191
+ def self.down
192
+ Post.drop_translation_table! :migrate_data => true
193
+ end
194
+ end
195
+ ```
196
+
197
+
198
+ In order to use a specific locale for migrated data, you can use `I18n.with_locale`:
199
+
200
+ ```ruby
201
+ I18n.with_locale(:bo) do
202
+ Post.create_translation_table!({
203
+ :title => :string,
204
+ :text => :text
205
+ }, {
206
+ :migrate_data => true
207
+ })
208
+ end
209
+ ```
210
+
211
+ ## Adding additional fields to the translation table
212
+
213
+ In order to add a new field to an existing translation table, you can use `add_translation_fields!`:
214
+
215
+ ```ruby
216
+ class AddAuthorToPost < ActiveRecord::Migration
217
+ def change
218
+ reversible do |dir|
219
+ dir.up do
220
+ Post.add_translation_fields! author: :text
221
+ end
222
+
223
+ dir.down do
224
+ remove_column :post_translations, :author
225
+ end
226
+ end
227
+ end
228
+ end
229
+ ```
230
+
231
+ NOTE: Remember to add the new field to the model:
232
+
233
+ ```ruby
234
+ translates :title, :author
235
+ ```
236
+ ## Gotchas
237
+
238
+ Because globalize uses the `:locale` key to specify the locale during
239
+ mass-assignment, you should avoid having a `locale` attribute on the parent
240
+ model.
241
+
242
+ ## Known Issues
243
+
244
+ If you're getting the `ActiveRecord::StatementInvalid: PG::NotNullViolation: ERROR: null value in column "column_name" violates not-null constraint` error, the only known way to deal with it as of now is to remove not-null constraint for the globalized columns:
245
+
246
+ ```ruby
247
+ class RemoveNullConstraintsFromResources < ActiveRecord::Migration
248
+ def change
249
+ change_column_null :resources, :column_name, true
250
+ end
251
+ end
252
+ ```
253
+
254
+ ## Versioning with Globalize
255
+
256
+ See the [globalize-versioning](https://github.com/globalize/globalize-versioning) gem.
257
+
258
+ ## I18n fallbacks for empty translations
259
+
260
+ It is possible to enable fallbacks for empty translations. It will depend on the
261
+ configuration setting you have set for I18n translations in your Rails config.
262
+
263
+ You can enable them by adding the next line to `config/application.rb` (or only
264
+ `config/environments/production.rb` if you only want them in production)
265
+
266
+ ```ruby
267
+ config.i18n.fallbacks = true
268
+ ```
269
+
270
+ By default, globalize will only use fallbacks when your translation model does
271
+ not exist or the translation value for the item you've requested is `nil`.
272
+ However it is possible to also use fallbacks for `blank` translations by adding
273
+ `:fallbacks_for_empty_translations => true` to the `translates` method.
274
+
275
+ ```ruby
276
+ class Post < ActiveRecord::Base
277
+ translates :title, :name
278
+ end
279
+
280
+ puts post.translations.inspect
281
+ # => [#<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
282
+ #<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>]
283
+
284
+ I18n.locale = :en
285
+ post.title # => 'Globalize rocks!'
286
+ post.name # => 'Globalize'
287
+
288
+ I18n.locale = :nl
289
+ post.title # => ''
290
+ post.name # => 'Globalize'
291
+ ```
292
+
293
+ ```ruby
294
+ class Post < ActiveRecord::Base
295
+ translates :title, :name, :fallbacks_for_empty_translations => true
296
+ end
297
+
298
+ puts post.translations.inspect
299
+ # => [#<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
300
+ #<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>]
301
+
302
+ I18n.locale = :en
303
+ post.title # => 'Globalize rocks!'
304
+ post.name # => 'Globalize'
305
+
306
+ I18n.locale = :nl
307
+ post.title # => 'Globalize rocks!'
308
+ post.name # => 'Globalize'
309
+ ```
310
+
311
+ ## Fallback locales to each other
312
+
313
+ It is possible to setup locales to fallback to each other.
314
+
315
+ ```ruby
316
+ class Post < ActiveRecord::Base
317
+ translates :title, :name
318
+ end
319
+
320
+ Globalize.fallbacks = {:en => [:en, :pl], :pl => [:pl, :en]}
321
+
322
+ I18n.locale = :en
323
+ en_post = Post.create(:title => 'en_title')
324
+
325
+ I18n.locale = :pl
326
+ pl_post = Post.create(:title => 'pl_title')
327
+ en_post.title # => 'en_title'
328
+
329
+ I18n.locale = :en
330
+ en_post.title # => 'en_title'
331
+ pl_post.title # => 'pl_title'
332
+ ```
333
+
334
+
335
+ ## Scoping objects by those with translations
336
+
337
+ To only return objects that have a translation for the given locale we can use
338
+ the `with_translations` scope. This will only return records that have a
339
+ translations for the passed in locale.
340
+
341
+ ```ruby
342
+ Post.with_translations('en')
343
+ # => [
344
+ #<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
345
+ #<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>
346
+ ]
347
+
348
+ Post.with_translations(I18n.locale)
349
+ # => [
350
+ #<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
351
+ #<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>
352
+ ]
353
+
354
+ Post.with_translations('de')
355
+ # => []
356
+ ```
357
+
358
+ ## Show different languages
359
+
360
+ In views, if there is content from different locales that you wish to display,
361
+ you should use the `with_locale` option with a block, as below:
362
+
363
+ ```erb
364
+ <% Globalize.with_locale(:en) do %>
365
+ <%= render "my_translated_partial" %>
366
+ <% end %>
367
+ ```
368
+
369
+ Your partial will now be rendered with the `:en` locale set as the current locale.
370
+
371
+ ## Interpolation
372
+
373
+ Globalize supports interpolation in a similar manner to I18n.
374
+
375
+ ```ruby
376
+ class Post < ActiveRecord::Base
377
+ translates :title
378
+ end
379
+
380
+ I18n.locale = :en
381
+ post.title = "Globalize %{superlative}!"
382
+
383
+ post.title
384
+ # #=> "Globalize %{superlative}!"
385
+
386
+ post.title(:foo => "bar")
387
+ # SomeError: missing interpolation argument :superlative
388
+
389
+ post.title(:superlative => "rocks")
390
+ # #=> "Globalize rocks!"
391
+ ```
392
+
393
+ ## Fragment caching
394
+
395
+ Don't forget to add globalize locale into the `cache_key` to separate different localizations of the record.
396
+ One of the possible ways to implement it:
397
+
398
+ ```ruby
399
+ # inside translated model
400
+ def cache_key
401
+ super + '-' + Globalize.locale.to_s
402
+ end
403
+ ```
404
+
405
+ ## Thread-safety
406
+
407
+ Globalize uses [request_store](https://github.com/steveklabnik/request_store) gem to clean up thread-global variable after every request.
408
+ RequestStore includes a Railtie that will configure everything properly for Rails 3+ apps.
409
+
410
+ If you're not using Rails, you may need to consult a RequestStore's [README](https://github.com/steveklabnik/request_store#no-rails-no-problem) to configure it.
411
+
412
+ ## Tutorials and articles
413
+ * [Go Global with Rails and I18n](http://www.sitepoint.com/go-global-rails-i18n/) - introductory article about i18n in Rails (Ilya Bodrov)
414
+
415
+ ## Official Globalize extensions
416
+
417
+ * [globalize-accessors](https://github.com/globalize/globalize-accessors) - generator of accessor methods for models. *(e.g. title_en, title_cz)*
418
+ * [globalize-versioning](https://github.com/globalize/globalize-versioning) - versioning support for using Globalize with [`paper_trail`](https://github.com/airblade/paper_trail). (compatible with Globalize 3.x and 4.x)
419
+
420
+ ## Alternative solutions
421
+
422
+ * [Traco](https://github.com/barsoom/traco) - use multiple columns in the same model (Barsoom)
423
+ * [Mobility](https://github.com/shioyama/mobility) - pluggable translation framework supporting many strategies, including translatable columns, translation tables and hstore/jsonb (Chris Salzberg)
424
+ * [hstore_translate](https://github.com/cfabianski/hstore_translate) - use PostgreSQL's hstore datatype to store translations, instead of separate translation tables (Cédric Fabianski)
425
+ * [json_translate](https://github.com/cfabianski/json_translate) - use PostgreSQL's json/jsonb datatype to store translations, instead of separate translation tables (Cédric Fabianski)
426
+ * [Trasto](https://github.com/yabawock/trasto) - store translations directly in the model in a Postgres Hstore column
427
+
428
+ ## Related solutions
429
+
430
+ * [friendly_id-globalize](https://github.com/norman/friendly_id-globalize) - lets you use Globalize to translate slugs (Norman Clarke)