globalize-rails5 5.1.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.
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)