globalize-r5 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) 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 +423 -0
  7. data/Rakefile +55 -0
  8. data/globalize.gemspec +27 -0
  9. data/issue_template.rb +38 -0
  10. data/lib/globalize.rb +90 -0
  11. data/lib/globalize/active_record.rb +14 -0
  12. data/lib/globalize/active_record/act_macro.rb +95 -0
  13. data/lib/globalize/active_record/adapter.rb +99 -0
  14. data/lib/globalize/active_record/adapter_dirty.rb +53 -0
  15. data/lib/globalize/active_record/attributes.rb +26 -0
  16. data/lib/globalize/active_record/class_methods.rb +122 -0
  17. data/lib/globalize/active_record/exceptions.rb +19 -0
  18. data/lib/globalize/active_record/instance_methods.rb +219 -0
  19. data/lib/globalize/active_record/migration.rb +192 -0
  20. data/lib/globalize/active_record/query_methods.rb +113 -0
  21. data/lib/globalize/active_record/translation.rb +45 -0
  22. data/lib/globalize/interpolation.rb +28 -0
  23. data/lib/globalize/version.rb +3 -0
  24. data/lib/i18n/missing_translations_log_handler.rb +41 -0
  25. data/lib/i18n/missing_translations_raise_handler.rb +25 -0
  26. data/lib/patches/active_record/persistence.rb +17 -0
  27. data/lib/patches/active_record/query_method.rb +3 -0
  28. data/lib/patches/active_record/rails4/query_method.rb +35 -0
  29. data/lib/patches/active_record/rails4/uniqueness_validator.rb +39 -0
  30. data/lib/patches/active_record/rails5/uniqueness_validator.rb +47 -0
  31. data/lib/patches/active_record/relation.rb +12 -0
  32. data/lib/patches/active_record/serialization.rb +21 -0
  33. data/lib/patches/active_record/uniqueness_validator.rb +5 -0
  34. data/lib/patches/active_record/xml_attribute_serializer.rb +23 -0
  35. metadata +206 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ce99c169b12c28c24f030dee7f36ffe81ed5d788
4
+ data.tar.gz: eb032c5d8f3aa55051125f34d53b5013e97c78e0
5
+ SHA512:
6
+ metadata.gz: 91650619c80ef94c9ce665f3d1e56b7474f8c210f08fe5d2719e45c8dfb40258fcb3e78cb5cf04c7165d29049ebde89f76d3e140480dbb5be9fed8699e469030
7
+ data.tar.gz: e0e4ae3ed75bfb67e4164bad25c748a96a6c71c4a7f357e7bf50bc5b9ff62c8c239a1d35f72921dd1778c6062a03f87bcb54e3fd014d4552bcccbd8dfda0373d
@@ -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', github: "jruby/activerecord-jdbc-adapter"
17
+ end
18
+
19
+ if !ENV['TRAVIS'] || ENV['DB'] == 'mysql'
20
+ gem 'activerecord-jdbcmysql-adapter', github: "jruby/activerecord-jdbc-adapter"
21
+ end
22
+
23
+ if !ENV['TRAVIS'] || %w(postgres postgresql).include?(ENV['DB'])
24
+ gem 'activerecord-jdbcpostgresql-adapter', github: "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,423 @@
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 globalize with Rails 5 add this in your Gemfile
32
+
33
+ ```ruby
34
+ gem 'activemodel-serializers-xml'
35
+ ```
36
+
37
+ To use the version of globalize for ActiveRecord 4.0 or 4.1, specify:
38
+
39
+ ```ruby
40
+ gem 'globalize', '~> 4.0.3'
41
+ ```
42
+
43
+ To use the version of globalize for ActiveRecord 3.1 or 3.2, specify:
44
+
45
+ ````ruby
46
+ gem 'globalize', '~> 3.1.0'
47
+ ````
48
+
49
+ (If you are using ActiveRecord 3.0, use version 3.0: `gem 'globalize', '3.0.4'`.)
50
+
51
+ 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.
52
+
53
+ ## Model translations
54
+
55
+ Model translations allow you to translate your models' attribute values. E.g.
56
+
57
+ ```ruby
58
+ class Post < ActiveRecord::Base
59
+ translates :title, :text
60
+ end
61
+ ```
62
+
63
+ Allows you to translate the attributes :title and :text per locale:
64
+
65
+ ```ruby
66
+ I18n.locale = :en
67
+ post.title # => Globalize rocks!
68
+
69
+ I18n.locale = :he
70
+ post.title # => גלובאלייז2 שולט!
71
+ ```
72
+
73
+ You can also set translations with mass-assignment by specifying the locale:
74
+
75
+ ```ruby
76
+ post.attributes = { title: 'גלובאלייז2 שולט!', locale: :he }
77
+ ```
78
+
79
+ In order to make this work, you'll need to add the appropriate translation tables.
80
+ Globalize comes with a handy helper method to help you do this.
81
+ It's called `create_translation_table!`. Here's an example:
82
+
83
+ Note that your migrations can use `create_translation_table!` and `drop_translation_table!`
84
+ only inside the `up` and `down` instance methods, respectively. You cannot use `create_translation_table!`
85
+ and `drop_translation_table!` inside the `change` instance method.
86
+
87
+ ### Creating translation tables
88
+
89
+ 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.
90
+
91
+ ```ruby
92
+ class CreatePosts < ActiveRecord::Migration
93
+ def change
94
+ create_table :posts do |t|
95
+ t.timestamps
96
+ end
97
+
98
+ reversible do |dir|
99
+ dir.up do
100
+ Post.create_translation_table! :title => :string, :text => :text
101
+ end
102
+
103
+ dir.down do
104
+ Post.drop_translation_table!
105
+ end
106
+ end
107
+ end
108
+ end
109
+ ```
110
+
111
+ Also, you can pass options for specific columns. Here’s an example:
112
+
113
+ ```ruby
114
+ class CreatePosts < ActiveRecord::Migration
115
+ def change
116
+ create_table :posts do |t|
117
+ t.timestamps
118
+ end
119
+
120
+ reversible do |dir|
121
+ dir.up do
122
+ Post.create_translation_table! :title => :string,
123
+ :text => {:type => :text, :null => false, :default => 'abc'}
124
+ end
125
+
126
+ dir.down do
127
+ Post.drop_translation_table!
128
+ end
129
+ end
130
+ end
131
+ end
132
+ ```
133
+
134
+ Note that the ActiveRecord model `Post` must already exist and have a `translates`
135
+ directive listing the translated fields.
136
+
137
+ ## Migrating existing data to and from the translated version
138
+
139
+ As well as creating a translation table, you can also use `create_translation_table!`
140
+ to migrate across any existing data to the default locale. This can also operate
141
+ in reverse to restore any translations from the default locale back to the model
142
+ when you don't want to use a translation table anymore using `drop_translation_table!`
143
+
144
+ This feature makes use of `untranslated_attributes` which allows access to the
145
+ model's attributes as they were before the translation was applied. Here's an
146
+ example (which assumes you already have a model called `Post` and its table
147
+ exists):
148
+
149
+ ```ruby
150
+ class TranslatePosts < ActiveRecord::Migration
151
+ def change
152
+ reversible do |dir|
153
+ dir.up do
154
+ Post.create_translation_table!({
155
+ :title => :string,
156
+ :text => :text
157
+ }, {
158
+ :migrate_data => true
159
+ })
160
+ end
161
+
162
+ dir.down do
163
+ Post.drop_translation_table! :migrate_data => true
164
+ end
165
+ end
166
+ end
167
+ end
168
+ ```
169
+
170
+ NOTE: Make sure you drop the translated columns from the parent table after all your data is safely migrated.
171
+
172
+ To automatically remove the translated columns from the parent table after the data migration, please use option `remove_source_columns`.
173
+
174
+ ```ruby
175
+ class TranslatePosts < ActiveRecord::Migration
176
+ def self.up
177
+ Post.create_translation_table!({
178
+ :title => :string,
179
+ :text => :text
180
+ }, {
181
+ :migrate_data => true,
182
+ :remove_source_columns => true
183
+ })
184
+ end
185
+
186
+ def self.down
187
+ Post.drop_translation_table! :migrate_data => true
188
+ end
189
+ end
190
+ ```
191
+
192
+
193
+ In order to use a specific locale for migrated data, you can use `I18n.with_locale`:
194
+
195
+ ```ruby
196
+ I18n.with_locale(:bo) do
197
+ Post.create_translation_table!({
198
+ :title => :string,
199
+ :text => :text
200
+ }, {
201
+ :migrate_data => true
202
+ })
203
+ end
204
+ ```
205
+
206
+ ## Adding additional fields to the translation table
207
+
208
+ In order to add a new field to an existing translation table, you can use `add_translation_fields!`:
209
+
210
+ ```ruby
211
+ class AddAuthorToPost < ActiveRecord::Migration
212
+ def change
213
+ reversible do |dir|
214
+ dir.up do
215
+ Post.add_translation_fields! author: :text
216
+ end
217
+
218
+ dir.down do
219
+ remove_column :post_translations, :author
220
+ end
221
+ end
222
+ end
223
+ end
224
+ ```
225
+
226
+ NOTE: Remember to add the new field to the model:
227
+
228
+ ```ruby
229
+ translates :title, :author
230
+ ```
231
+ ## Gotchas
232
+
233
+ Because globalize uses the `:locale` key to specify the locale during
234
+ mass-assignment, you should avoid having a `locale` attribute on the parent
235
+ model.
236
+
237
+ ## Known Issues
238
+
239
+ 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:
240
+
241
+ ```ruby
242
+ class RemoveNullConstraintsFromResources < ActiveRecord::Migration
243
+ def change
244
+ change_column_null :resources, :column_name, true
245
+ end
246
+ end
247
+ ```
248
+
249
+ ## Versioning with Globalize
250
+
251
+ See the [globalize-versioning](https://github.com/globalize/globalize-versioning) gem.
252
+
253
+ ## I18n fallbacks for empty translations
254
+
255
+ It is possible to enable fallbacks for empty translations. It will depend on the
256
+ configuration setting you have set for I18n translations in your Rails config.
257
+
258
+ You can enable them by adding the next line to `config/application.rb` (or only
259
+ `config/environments/production.rb` if you only want them in production)
260
+
261
+ ```ruby
262
+ config.i18n.fallbacks = true
263
+ ```
264
+
265
+ By default, globalize will only use fallbacks when your translation model does
266
+ not exist or the translation value for the item you've requested is `nil`.
267
+ However it is possible to also use fallbacks for `blank` translations by adding
268
+ `:fallbacks_for_empty_translations => true` to the `translates` method.
269
+
270
+ ```ruby
271
+ class Post < ActiveRecord::Base
272
+ translates :title, :name
273
+ end
274
+
275
+ puts post.translations.inspect
276
+ # => [#<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
277
+ #<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>]
278
+
279
+ I18n.locale = :en
280
+ post.title # => 'Globalize rocks!'
281
+ post.name # => 'Globalize'
282
+
283
+ I18n.locale = :nl
284
+ post.title # => ''
285
+ post.name # => 'Globalize'
286
+ ```
287
+
288
+ ```ruby
289
+ class Post < ActiveRecord::Base
290
+ translates :title, :name, :fallbacks_for_empty_translations => true
291
+ end
292
+
293
+ puts post.translations.inspect
294
+ # => [#<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
295
+ #<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>]
296
+
297
+ I18n.locale = :en
298
+ post.title # => 'Globalize rocks!'
299
+ post.name # => 'Globalize'
300
+
301
+ I18n.locale = :nl
302
+ post.title # => 'Globalize rocks!'
303
+ post.name # => 'Globalize'
304
+ ```
305
+
306
+ ## Fallback locales to each other
307
+
308
+ It is possible to setup locales to fallback to each other.
309
+
310
+ ```ruby
311
+ class Post < ActiveRecord::Base
312
+ translates :title, :name
313
+ end
314
+
315
+ Globalize.fallbacks = {:en => [:en, :pl], :pl => [:pl, :en]}
316
+
317
+ I18n.locale = :en
318
+ en_post = Post.create(:title => 'en_title')
319
+
320
+ I18n.locale = :pl
321
+ pl_post = Post.create(:title => 'pl_title')
322
+ en_post.title # => 'en_title'
323
+
324
+ I18n.locale = :en
325
+ en_post.title # => 'en_title'
326
+ pl_post.title # => 'pl_title'
327
+ ```
328
+
329
+
330
+ ## Scoping objects by those with translations
331
+
332
+ To only return objects that have a translation for the given locale we can use
333
+ the `with_translations` scope. This will only return records that have a
334
+ translations for the passed in locale.
335
+
336
+ ```ruby
337
+ Post.with_translations('en')
338
+ # => [
339
+ #<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
340
+ #<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>
341
+ ]
342
+
343
+ Post.with_translations(I18n.locale)
344
+ # => [
345
+ #<Post::Translation id: 1, post_id: 1, locale: "en", title: "Globalize rocks!", name: "Globalize">,
346
+ #<Post::Translation id: 2, post_id: 1, locale: "nl", title: '', name: nil>
347
+ ]
348
+
349
+ Post.with_translations('de')
350
+ # => []
351
+ ```
352
+
353
+ ## Show different languages
354
+
355
+ In views, if there is content from different locales that you wish to display,
356
+ you should use the `with_locale` option with a block, as below:
357
+
358
+ ```erb
359
+ <% Globalize.with_locale(:en) do %>
360
+ <%= render "my_translated_partial" %>
361
+ <% end %>
362
+ ```
363
+
364
+ Your partial will now be rendered with the `:en` locale set as the current locale.
365
+
366
+ ## Interpolation
367
+
368
+ Globalize supports interpolation in a similar manner to I18n.
369
+
370
+ ```ruby
371
+ class Post < ActiveRecord::Base
372
+ translates :title
373
+ end
374
+
375
+ I18n.locale = :en
376
+ post.title = "Globalize %{superlative}!"
377
+
378
+ post.title
379
+ # #=> "Globalize %{superlative}!"
380
+
381
+ post.title(:foo => "bar")
382
+ # SomeError: missing interpolation argument :superlative
383
+
384
+ post.title(:superlative => "rocks")
385
+ # #=> "Globalize rocks!"
386
+ ```
387
+
388
+ ## Fragment caching
389
+
390
+ Don't forget to add globalize locale into the `cache_key` to separate different localizations of the record.
391
+ One of the possible ways to implement it:
392
+
393
+ ```ruby
394
+ # inside translated model
395
+ def cache_key
396
+ super + '-' + Globalize.locale.to_s
397
+ end
398
+ ```
399
+
400
+ ## Thread-safety
401
+
402
+ Globalize uses [request_store](https://github.com/steveklabnik/request_store) gem to clean up thread-global variable after every request.
403
+ RequestStore includes a Railtie that will configure everything properly for Rails 3+ apps.
404
+
405
+ 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.
406
+
407
+ ## Tutorials and articles
408
+ * [Go Global with Rails and I18n](http://www.sitepoint.com/go-global-rails-i18n/) - introductory article about i18n in Rails (Ilya Bodrov)
409
+
410
+ ## Official Globalize extensions
411
+
412
+ * [globalize-accessors](https://github.com/globalize/globalize-accessors) - generator of accessor methods for models. *(e.g. title_en, title_cz)*
413
+ * [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)
414
+
415
+ ## Alternative solutions
416
+
417
+ * [Traco](https://github.com/barsoom/traco) - use multiple columns in the same model (Barsoom)
418
+ * [hstore_translate](http://github.com/robworley/hstore_translate) - use PostgreSQL's hstore datatype to store translations, instead of separate translation tables (Rob Worley)
419
+ * [Trasto](https://github.com/yabawock/trasto) - store translations directly in the model in a Postgres Hstore column
420
+
421
+ ## Related solutions
422
+
423
+ * [friendly_id-globalize](https://github.com/norman/friendly_id-globalize) - lets you use Globalize to translate slugs (Norman Clarke)