globalize-rails5 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +111 -0
- data/CONTRIBUTING.md +37 -0
- data/Gemfile +26 -0
- data/LICENSE +22 -0
- data/README.md +430 -0
- data/Rakefile +55 -0
- data/lib/globalize.rb +90 -0
- data/lib/globalize/active_record.rb +14 -0
- data/lib/globalize/active_record/act_macro.rb +111 -0
- data/lib/globalize/active_record/adapter.rb +99 -0
- data/lib/globalize/active_record/adapter_dirty.rb +54 -0
- data/lib/globalize/active_record/attributes.rb +26 -0
- data/lib/globalize/active_record/class_methods.rb +124 -0
- data/lib/globalize/active_record/exceptions.rb +13 -0
- data/lib/globalize/active_record/instance_methods.rb +218 -0
- data/lib/globalize/active_record/migration.rb +210 -0
- data/lib/globalize/active_record/query_methods.rb +98 -0
- data/lib/globalize/active_record/translation.rb +45 -0
- data/lib/globalize/interpolation.rb +28 -0
- data/lib/globalize/version.rb +3 -0
- data/lib/i18n/missing_translations_log_handler.rb +41 -0
- data/lib/i18n/missing_translations_raise_handler.rb +25 -0
- data/lib/patches/active_record/persistence.rb +17 -0
- data/lib/patches/active_record/query_method.rb +3 -0
- data/lib/patches/active_record/rails4/query_method.rb +35 -0
- data/lib/patches/active_record/rails4/uniqueness_validator.rb +42 -0
- data/lib/patches/active_record/rails5/uniqueness_validator.rb +47 -0
- data/lib/patches/active_record/relation.rb +12 -0
- data/lib/patches/active_record/serialization.rb +21 -0
- data/lib/patches/active_record/uniqueness_validator.rb +5 -0
- data/lib/patches/active_record/xml_attribute_serializer.rb +23 -0
- metadata +204 -0
checksums.yaml
ADDED
@@ -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
|
data/CHANGELOG.md
ADDED
@@ -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.
|
data/CONTRIBUTING.md
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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)
|