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