embedded_localization 0.2.5 → 1.0.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.
- data/README.textile +26 -7
- data/Rakefile +17 -0
- data/embedded_localization.gemspec +4 -1
- data/lib/embedded_localization/active_record/act_macro.rb +11 -7
- data/lib/embedded_localization/active_record/instance_methods.rb +17 -9
- data/lib/embedded_localization/version.rb +1 -1
- data/lib/embedded_localization.rb +2 -2
- data/spec/embedded_localization/native_column_spec.rb +139 -0
- data/spec/embedded_localization/simple_model_spec.rb +139 -0
- data/spec/models.rb +9 -0
- data/spec/schema.rb +18 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +20 -0
- metadata +107 -35
- checksums.yaml +0 -7
data/README.textile
CHANGED
@@ -12,7 +12,7 @@ h2. Requirements
|
|
12
12
|
ActiveRecord > 3.0.0.rc
|
13
13
|
I18n
|
14
14
|
|
15
|
-
Tested with Rails 3.2.2
|
15
|
+
Tested with Rails 3.2.2 , 3.2.16
|
16
16
|
|
17
17
|
h2. Installation
|
18
18
|
|
@@ -139,9 +139,9 @@ Each class which uses Embedded_Localization will have these additional methods d
|
|
139
139
|
<li>Klass.translated_attributes
|
140
140
|
<li>Klass.translated?
|
141
141
|
<li>Klass.fallbacks?
|
142
|
-
</ul>
|
142
|
+
</ul>
|
143
143
|
|
144
|
-
e.g.:
|
144
|
+
e.g.:
|
145
145
|
|
146
146
|
<pre><code>
|
147
147
|
Genre.translated_attributes # => [:name,:description]
|
@@ -162,7 +162,19 @@ Each model instance of a class which uses Embedded_Localization will have these
|
|
162
162
|
<li>directly setting and getting attribute values for a given locale; without having to change <code>I18n.locale</code>
|
163
163
|
</ul>
|
164
164
|
|
165
|
-
|
165
|
+
Notes:
|
166
|
+
|
167
|
+
<pre><code>translated_locales</code></pre> lists the super-set of all locales, including the default locale, even if there is no value set for a specific attribute.
|
168
|
+
For a new empty record, this will report I18n.default_locale.
|
169
|
+
|
170
|
+
translated_locales reports which translations / languages are possible.
|
171
|
+
|
172
|
+
<pre><code>translation_coverage</code></pre> only lists locales for which a non-nil value is set.
|
173
|
+
For a new empty record, this will be empty.
|
174
|
+
|
175
|
+
translation_coverage reports for which languages translations exist (actual values exist).
|
176
|
+
|
177
|
+
e.g.:
|
166
178
|
|
167
179
|
<pre><code>
|
168
180
|
I18n.locale = :jp
|
@@ -177,8 +189,8 @@ e.g.:
|
|
177
189
|
g.translated_attributes # => [:name,:description]
|
178
190
|
g.translated? # => true
|
179
191
|
|
180
|
-
g.translation_coverage
|
181
|
-
# => {"name"=>["en", "ko", "jp"] , "description"=>["en", "de", "fr", "ko", "jp", "es"]}
|
192
|
+
g.translation_coverage
|
193
|
+
# => {"name"=>["en", "ko", "jp"] , "description"=>["en", "de", "fr", "ko", "jp", "es"]}
|
182
194
|
|
183
195
|
g.translation_coverage(:name)
|
184
196
|
# => {"name"=>["en", "ko", "jp"]}
|
@@ -207,6 +219,13 @@ If your requirements are different, my approach might not work for you. In that
|
|
207
219
|
|
208
220
|
h2. Changes
|
209
221
|
|
222
|
+
|
223
|
+
h3. 1.0.0 (2014-01-11)
|
224
|
+
* adding rspec tests.
|
225
|
+
* fixing issue #6: translated fields for new records were not nil
|
226
|
+
* fixing issue #7: translation_missing for new records is breaking
|
227
|
+
|
228
|
+
|
210
229
|
h3. 0.2.5 (2013-11-02)
|
211
230
|
* adding MIT and GPL-2 licenses to gem-spec file; contact me if you need another license
|
212
231
|
|
@@ -214,7 +233,7 @@ h3. 0.2.4 (2012-03-02)
|
|
214
233
|
* Issue #5 : bugfix for attr_writer
|
215
234
|
|
216
235
|
h3. 0.2.3 (2012-03-02)
|
217
|
-
* Issue #4 : bugfix for attr_writer - no longer updates attributes if value didn't change => timestamps don't change in that case
|
236
|
+
* Issue #4 : bugfix for attr_writer - no longer updates attributes if value didn't change => timestamps don't change in that case
|
218
237
|
|
219
238
|
h3. 0.2.2 (2012-02-06)
|
220
239
|
* bugfix for attr_writer
|
data/Rakefile
CHANGED
@@ -1 +1,18 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rake'
|
5
|
+
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
|
8
|
+
desc "Run RSpec"
|
9
|
+
RSpec::Core::RakeTask.new do |t|
|
10
|
+
t.verbose = false
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Run specs for all test cases"
|
14
|
+
task :spec_all do
|
15
|
+
system "rake spec"
|
16
|
+
end
|
17
|
+
|
18
|
+
task :default => :spec
|
@@ -22,6 +22,9 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.require_paths = ["lib"]
|
23
23
|
s.licenses = ['MIT','GPL-2']
|
24
24
|
# specify any dependencies here; for example:
|
25
|
-
|
25
|
+
s.add_development_dependency "rspec"
|
26
|
+
s.add_development_dependency "activerecord", "~> 3.2.0"
|
27
|
+
s.add_development_dependency "i18n"
|
28
|
+
s.add_development_dependency "sqlite3"
|
26
29
|
# s.add_runtime_dependency "rest-client"
|
27
30
|
end
|
@@ -5,7 +5,7 @@ module EmbeddedLocalization
|
|
5
5
|
return if translates? # cludge to make sure we don't set this up twice..
|
6
6
|
|
7
7
|
# for details about I18n fallbacks, check the source:
|
8
|
-
# i18n-0.6.0/lib/i18n/backend/fallbacks.rb
|
8
|
+
# i18n-0.6.0/lib/i18n/backend/fallbacks.rb
|
9
9
|
# i18n-0.6.0/lib/i18n/locale/fallbacks.rb
|
10
10
|
|
11
11
|
# options[:fallbacks] => true or false # not used at this time
|
@@ -24,7 +24,7 @@ module EmbeddedLocalization
|
|
24
24
|
#+
|
25
25
|
|
26
26
|
serialize :i18n # we should also protect it from direct assignment by the user
|
27
|
-
|
27
|
+
|
28
28
|
#-
|
29
29
|
# if Mongoid::Document is in the list of classes which extends the class we are included into:
|
30
30
|
# ::Rails::Railtie.subclasses.map(&:to_s).include?("Rails::Mongoid::Railtie")
|
@@ -32,7 +32,7 @@ module EmbeddedLocalization
|
|
32
32
|
# field :i18n, type: Hash
|
33
33
|
# but on the other hand, Mongoid now supports "localized fields" -- so we don't need to re-implement this.
|
34
34
|
# Yay! Durran Jordan is awesome! :-) See: http://mongoid.org/docs/documents/localized.html
|
35
|
-
#
|
35
|
+
#
|
36
36
|
# NOTE: I like how Durran implemented the localization in Mongoid.. too bad I didn't see that before.
|
37
37
|
# I'm thinking of re-writing this gem to store the localization hash per attribute... hmm... hmm... thinking...
|
38
38
|
# there would be a couple of advantages to store the I18n-hash per attribute:
|
@@ -40,7 +40,7 @@ module EmbeddedLocalization
|
|
40
40
|
# - works well with rails scaffolding and with protection of attributes (attr_protected / attr_accessible)
|
41
41
|
# - we can easily hide the internal hash by re-defining the attr-accessors for doing the I18n
|
42
42
|
# - we can better add the per-attribute versioning, which is planned
|
43
|
-
# -
|
43
|
+
# -
|
44
44
|
#+
|
45
45
|
|
46
46
|
after_initialize :initialize_i18n_hashes
|
@@ -48,12 +48,16 @@ module EmbeddedLocalization
|
|
48
48
|
# dynamically define the accessors for the translated attributes:
|
49
49
|
|
50
50
|
translated_attribute_names.each do |attr_name|
|
51
|
-
class_eval do
|
51
|
+
class_eval do
|
52
52
|
# define the getter method
|
53
53
|
#
|
54
54
|
define_method(attr_name) do |locale = I18n.locale|
|
55
55
|
if self.i18n.has_key?(locale)
|
56
|
-
self.i18n[
|
56
|
+
if self.i18n[locale].keys.include?(attr_name)
|
57
|
+
self.i18n[ locale ][attr_name]
|
58
|
+
else
|
59
|
+
nil
|
60
|
+
end
|
57
61
|
else
|
58
62
|
# fallback to the I18n.default_locale if we do fallbacks:
|
59
63
|
if self.class.fallbacks? && self.i18n[ I18n.default_locale ]
|
@@ -84,7 +88,7 @@ module EmbeddedLocalization
|
|
84
88
|
end
|
85
89
|
end
|
86
90
|
end
|
87
|
-
|
91
|
+
|
88
92
|
def translates?
|
89
93
|
included_modules.include?(InstanceMethods)
|
90
94
|
end
|
@@ -9,16 +9,20 @@ module EmbeddedLocalization
|
|
9
9
|
locale = locale.downcase.to_sym if locale.class == String # ensure that locale is always a symbol
|
10
10
|
|
11
11
|
if self.i18n.has_key?(locale)
|
12
|
-
self.i18n[locale]
|
12
|
+
if self.i18n[locale].keys.include?(attr_name)
|
13
|
+
self.i18n[locale][attr_name]
|
14
|
+
else
|
15
|
+
nil
|
16
|
+
end
|
13
17
|
else
|
14
18
|
if self.class.fallbacks? && self.i18n[ I18n.default_locale ]
|
15
|
-
return self.i18n[ I18n.default_locale ][attr_name]
|
19
|
+
return self.i18n[ I18n.default_locale ][attr_name]
|
16
20
|
else
|
17
21
|
return nil
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
21
|
-
|
25
|
+
|
22
26
|
# - will convert given locale to symbol, e.g. "en","En" to :en
|
23
27
|
|
24
28
|
def set_localized_attribute(attr_name, locale, new_translation)
|
@@ -44,15 +48,15 @@ module EmbeddedLocalization
|
|
44
48
|
def translated_locales
|
45
49
|
self.i18n.keys
|
46
50
|
end
|
47
|
-
|
48
|
-
# Returns Array of Symbols for all attributes of this class,
|
51
|
+
|
52
|
+
# Returns Array of Symbols for all attributes of this class,
|
49
53
|
# which have translations through acts_as_i18n.
|
50
54
|
# returns an Array of Symbols
|
51
55
|
#
|
52
56
|
def translated_attributes
|
53
57
|
self.class.translated_attributes
|
54
58
|
end
|
55
|
-
|
59
|
+
|
56
60
|
# Checks whether field with given name is translated field.
|
57
61
|
# Param String or Symbol
|
58
62
|
# Returns true or false
|
@@ -75,8 +79,12 @@ module EmbeddedLocalization
|
|
75
79
|
end
|
76
80
|
if attribute.nil?
|
77
81
|
return attrs
|
78
|
-
|
79
|
-
|
82
|
+
elsif attrs[attribute.to_sym]
|
83
|
+
attrs[attribute.to_sym]
|
84
|
+
elsif translated?(attribute)
|
85
|
+
[]
|
86
|
+
else # if it's not a translated attribute, return nil
|
87
|
+
nil
|
80
88
|
end
|
81
89
|
end
|
82
90
|
|
@@ -85,7 +93,7 @@ module EmbeddedLocalization
|
|
85
93
|
# If an attribute has complete translation coverage, it will not be listed
|
86
94
|
# If the result is an empty Hash, then no attributes are missing translations
|
87
95
|
#
|
88
|
-
# Needs all the desired locales to be present in 'translated_locales'
|
96
|
+
# Needs all the desired locales to be present in 'translated_locales'
|
89
97
|
# e.g. each locale must be present in at least one of the translated attributes
|
90
98
|
#
|
91
99
|
def translation_missing( attribute = nil )
|
@@ -17,11 +17,11 @@ ActiveRecord::Base.extend(EmbeddedLocalization::ActiveRecord::ActMacro)
|
|
17
17
|
# Fallbacks: https://github.com/svenfuchs/i18n/wiki/Fallbacks
|
18
18
|
#
|
19
19
|
# The problem is that the I18n backends are meant for static strings in the views, helpers, etc.; not for model data.
|
20
|
-
# Switching on the current I18n backend's fallbacks will allow us to use that backend's mappings from one locale to the fallbacks,
|
20
|
+
# Switching on the current I18n backend's fallbacks will allow us to use that backend's mappings from one locale to the fallbacks,
|
21
21
|
# but we still need to search for the translated module data in our serialized i18n attribute hash ourselves.
|
22
22
|
|
23
23
|
# to enable I18n fallbacks:
|
24
|
-
# require "i18n/backend/fallbacks"
|
24
|
+
# require "i18n/backend/fallbacks"
|
25
25
|
# I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
|
26
26
|
|
27
27
|
# Thread.current[:i18n_config].backend
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
I18n.locale = :en
|
5
|
+
|
6
|
+
# e.g. the model "Movie" has :title as a translated field,
|
7
|
+
# but also has :title as a native attribute for the model.
|
8
|
+
|
9
|
+
describe 'model has translated field with attribute of that same name' do
|
10
|
+
let(:movie){ Movie.new }
|
11
|
+
let(:title_en){ "Blade Runner" }
|
12
|
+
let(:title_ru){'аЕЦСЫХИ ОН КЕГБХЧ'}
|
13
|
+
let(:title_tr){"Ölüm takibi"}
|
14
|
+
let(:title_de){"Der Blade Runner"}
|
15
|
+
let(:blade_runner){ Movie.new(:title => title_en) }
|
16
|
+
|
17
|
+
it 'reports it translates' do
|
18
|
+
Movie.translates?.should be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'correctly reports the list of translated_attributes' do
|
22
|
+
Movie.translated_attributes.sort.should eq [:description, :title]
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'correctly reports the list of translated_attribute_names' do
|
26
|
+
Movie.translated_attribute_names.sort.should eq [:description, :title]
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'correcty shows the translated attribute as translated' do
|
30
|
+
Movie.translated?(:title).should be_true
|
31
|
+
Movie.translated?(:description).should be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'correcty shows not translated attribute' do
|
35
|
+
Movie.translated?(:other).should be_false
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'correctly reports translated_locales for new record' do
|
39
|
+
movie.translated_locales.should eq [I18n.default_locale]
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'correctly reports translation_missing for new record' do
|
43
|
+
movie.translation_missing.should be_true
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'creates the accessor methods' do
|
47
|
+
movie.methods.should include(:title)
|
48
|
+
movie.methods.should include(:title=)
|
49
|
+
movie.methods.should include(:description)
|
50
|
+
movie.methods.should include(:description=)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'correctly reports translated field for new record for default locale' do
|
54
|
+
movie.title.should be_nil
|
55
|
+
movie.description.should be_nil
|
56
|
+
movie.description( I18n.default_locale ).should be_nil
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'correctly reports translated field for new record for other locale' do
|
60
|
+
movie.title(:ko).should be_nil
|
61
|
+
movie.description(:de).should be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'correctly reports translation_coverage for new record' do
|
65
|
+
movie.translation_coverage.should eq Hash.new
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'correctly reports translation_goverate for attributes of new record' do
|
69
|
+
movie.translation_coverage(:title).should eq []
|
70
|
+
movie.translation_coverage(:description).should eq []
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'translated_coverage returns nil for not-translated attributes' do
|
74
|
+
movie.translation_coverage(:other).should be_nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'correctly reports translation_missing for new record' do
|
78
|
+
movie.translation_missing.should == {:description=>[:en], :title=>[:en]}
|
79
|
+
movie.translation_missing(:title).should eq [:en]
|
80
|
+
movie.translation_missing(:description).should eq [:en]
|
81
|
+
end
|
82
|
+
|
83
|
+
# when setting all fields in the default locale's languange:
|
84
|
+
it 'correctly reports translation_missing for updated record' do
|
85
|
+
movie.title = title_en
|
86
|
+
movie.description = "an awesome movie"
|
87
|
+
movie.save
|
88
|
+
movie.translation_missing.should eq Hash.new
|
89
|
+
movie.translation_missing(:title).should eq nil
|
90
|
+
movie.translation_missing(:description).should eq nil
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'correctly reports translated_coverage for updated record' do
|
94
|
+
movie.title = title_en
|
95
|
+
movie.description = "an awesome movie"
|
96
|
+
movie.save
|
97
|
+
movie.translation_coverage.should == {:title=>[:en], :description=>[:en]}
|
98
|
+
movie.translation_coverage(:title).should eq [:en]
|
99
|
+
movie.translation_coverage(:description).should eq [:en]
|
100
|
+
end
|
101
|
+
|
102
|
+
# when setting all fields in additional languanges:
|
103
|
+
it 'correctly reports values, translation_coverage, translation_missing for updated record' do
|
104
|
+
movie.title = title_en
|
105
|
+
movie.description = "an awesome movie"
|
106
|
+
I18n.locale = :ru
|
107
|
+
movie.title = title_ru
|
108
|
+
movie.set_localized_attribute(:title , :tr, title_tr)
|
109
|
+
I18n.locale = :de
|
110
|
+
movie.description = "ein grossartiger Film"
|
111
|
+
I18n.locale = I18n.default_locale # MAKE SURE you switch back to your default
|
112
|
+
movie.save
|
113
|
+
movie.reload
|
114
|
+
movie.title(:en).should eq title_en
|
115
|
+
movie.title(:tr).should eq title_tr
|
116
|
+
movie.get_localized_attribute(:title, :ru).should eq title_ru
|
117
|
+
|
118
|
+
# what values are actually present
|
119
|
+
movie.translation_coverage.should == {:title=>[:en, :ru, :tr], :description=>[:en, :de]}
|
120
|
+
movie.translation_coverage(:title).should eq [:en,:ru,:tr]
|
121
|
+
movie.translation_coverage(:description).should eq [:en,:de]
|
122
|
+
|
123
|
+
# what values are missing
|
124
|
+
movie.translation_missing.should == {:description=>[:ru, :tr], :title=>[:de]}
|
125
|
+
movie.translation_missing(:title).should eq [:de]
|
126
|
+
movie.translation_missing(:description).should eq [:ru,:tr]
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'can assign the translated field' do
|
130
|
+
movie.title = title_en
|
131
|
+
movie.save.should be_true
|
132
|
+
movie.title.should eq title_en
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'correctly shows the attribute for new record' do
|
136
|
+
blade_runner.title.should eq title_en
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
I18n.locale = :en
|
5
|
+
|
6
|
+
# e.g. the model "Genre" has :name as a translated field,
|
7
|
+
# but does not have :name as a native attribute for the model.
|
8
|
+
# It is only defined as a virtual attribute in the :i18n hash.
|
9
|
+
|
10
|
+
describe 'model has translated field without attribute of that same name' do
|
11
|
+
let(:genre){ Genre.new }
|
12
|
+
let(:genre_name_en){"Science Fiction"}
|
13
|
+
let(:genre_name_jp){"サイエンスフィクション"}
|
14
|
+
let(:genre_name_ko){"공상 과학 소설"}
|
15
|
+
let(:scifi){ Genre.new(:name => genre_name_en) }
|
16
|
+
|
17
|
+
it 'reports it translates' do
|
18
|
+
Genre.translates?.should be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'correctly reports the list of translated_attributes' do
|
22
|
+
Genre.translated_attributes.sort.should eq [:description, :name]
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'correctly reports the list of translated_attribute_names' do
|
26
|
+
Genre.translated_attribute_names.sort.should eq [:description, :name]
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'correcty shows the translated attribute as translated' do
|
30
|
+
Genre.translated?(:name).should be_true
|
31
|
+
Genre.translated?(:description).should be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'correcty shows not translated attribute' do
|
35
|
+
Genre.translated?(:other).should be_false
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'correctly reports translated_locales for new record' do
|
39
|
+
genre.translated_locales.should eq [I18n.default_locale]
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'correctly reports translation_missing for new record' do
|
43
|
+
genre.translation_missing.should be_true
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'creates the accessor methods' do
|
47
|
+
genre.methods.should include(:name)
|
48
|
+
genre.methods.should include(:name=)
|
49
|
+
genre.methods.should include(:description)
|
50
|
+
genre.methods.should include(:description=)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'correctly reports translated field for new record for default locale' do
|
54
|
+
genre.name.should be_nil
|
55
|
+
genre.description.should be_nil
|
56
|
+
genre.description( I18n.default_locale ).should be_nil
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'correctly reports translated field for new record for other locale' do
|
60
|
+
genre.name(:ko).should be_nil
|
61
|
+
genre.description(:de).should be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'correctly reports translation_coverage for new record' do
|
65
|
+
genre.translation_coverage.should eq Hash.new
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'correctly reports translation_goverate for attributes of new record' do
|
69
|
+
genre.translation_coverage(:name).should eq []
|
70
|
+
genre.translation_coverage(:description).should eq []
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'translated_coverage returns nil for not-translated attributes' do
|
74
|
+
genre.translation_coverage(:other).should be_nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'correctly reports translation_missing for new record' do
|
78
|
+
genre.translation_missing.should == {:description=>[:en], :name=>[:en]}
|
79
|
+
genre.translation_missing(:name).should eq [:en]
|
80
|
+
genre.translation_missing(:description).should eq [:en]
|
81
|
+
end
|
82
|
+
|
83
|
+
# when setting all fields in the default locale's languange:
|
84
|
+
it 'correctly reports translation_missing for updated record' do
|
85
|
+
genre.name = genre_name_en
|
86
|
+
genre.description = "an awesome genre"
|
87
|
+
genre.save
|
88
|
+
genre.translation_missing.should eq Hash.new
|
89
|
+
genre.translation_missing(:name).should eq nil
|
90
|
+
genre.translation_missing(:description).should eq nil
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'correctly reports translated_coverage for updated record' do
|
94
|
+
genre.name = genre_name_en
|
95
|
+
genre.description = "an awesome genre"
|
96
|
+
genre.save
|
97
|
+
genre.translation_coverage.should == {:name=>[:en], :description=>[:en]}
|
98
|
+
genre.translation_coverage(:name).should eq [:en]
|
99
|
+
genre.translation_coverage(:description).should eq [:en]
|
100
|
+
end
|
101
|
+
|
102
|
+
# when setting all fields in additional languanges:
|
103
|
+
it 'correctly reports values, translation_coverage, translation_missing for updated record' do
|
104
|
+
genre.name = genre_name_en
|
105
|
+
genre.description = "an awesome genre"
|
106
|
+
I18n.locale = :jp
|
107
|
+
genre.name = genre_name_jp
|
108
|
+
genre.set_localized_attribute(:name, :ko, genre_name_ko)
|
109
|
+
I18n.locale = :de
|
110
|
+
genre.description = "ein grossartiger Film"
|
111
|
+
I18n.locale = I18n.default_locale # MAKE SURE you switch back to your default
|
112
|
+
genre.save
|
113
|
+
genre.reload
|
114
|
+
genre.name(:en).should eq genre_name_en
|
115
|
+
genre.get_localized_attribute(:name, :jp).should eq genre_name_jp
|
116
|
+
genre.name(:ko).should eq genre_name_ko
|
117
|
+
|
118
|
+
# what values are actually present
|
119
|
+
genre.translation_coverage.should == {:name=>[:en, :jp, :ko], :description=>[:en, :de]}
|
120
|
+
genre.translation_coverage(:name).should eq [:en, :jp, :ko]
|
121
|
+
genre.translation_coverage(:description).should eq [:en,:de]
|
122
|
+
|
123
|
+
# what values are missing
|
124
|
+
genre.translation_missing.should == {:description=>[:jp, :ko], :name=>[:de]}
|
125
|
+
genre.translation_missing(:name).should eq [:de]
|
126
|
+
genre.translation_missing(:description).should eq [:jp, :ko]
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'can assign the translated field' do
|
130
|
+
genre.name = genre_name_en
|
131
|
+
genre.save.should be_true
|
132
|
+
genre.name.should eq genre_name_en
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'correctly shows the attribute for new record' do
|
136
|
+
scifi.name.should eq genre_name_en
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
data/spec/models.rb
ADDED
data/spec/schema.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
self.verbose = false
|
3
|
+
|
4
|
+
create_table :genres, :force => true do |t|
|
5
|
+
t.text :i18n
|
6
|
+
|
7
|
+
t.string :other
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
create_table :movies, :force => true do |t|
|
12
|
+
t.string :title
|
13
|
+
t.text :i18n
|
14
|
+
|
15
|
+
t.string :other
|
16
|
+
t.timestamps
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_record'
|
3
|
+
require 'i18n'
|
4
|
+
require 'bundler/setup'
|
5
|
+
|
6
|
+
Bundler.require(:default)
|
7
|
+
|
8
|
+
require 'embedded_localization'
|
9
|
+
|
10
|
+
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
11
|
+
|
12
|
+
load File.dirname(__FILE__) + '/schema.rb'
|
13
|
+
require File.dirname(__FILE__) + '/models.rb'
|
14
|
+
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
18
|
+
config.filter_run :focus => true
|
19
|
+
config.run_all_when_everything_filtered = true
|
20
|
+
end
|
metadata
CHANGED
@@ -1,27 +1,89 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: embedded_localization
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
|
-
authors:
|
7
|
+
authors:
|
7
8
|
- Tilo Sloboda
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
date: 2014-01-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activerecord
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 3.2.0
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.2.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: i18n
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: sqlite3
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: ! 'Rails I18n: Embedded_Localization for ActiveRecord 3 is very lightweight,
|
79
|
+
and allows you to transparently store translations of attributes right inside each
|
80
|
+
record -- no extra database tables needed to store the localization data!'
|
81
|
+
email:
|
17
82
|
- tilo.sloboda@gmail.com
|
18
83
|
executables: []
|
19
|
-
|
20
84
|
extensions: []
|
21
|
-
|
22
85
|
extra_rdoc_files: []
|
23
|
-
|
24
|
-
files:
|
86
|
+
files:
|
25
87
|
- .gitignore
|
26
88
|
- Gemfile
|
27
89
|
- README.textile
|
@@ -34,32 +96,42 @@ files:
|
|
34
96
|
- lib/embedded_localization/active_record/instance_methods.rb
|
35
97
|
- lib/embedded_localization/version.rb
|
36
98
|
- lib/extensions/hash.rb
|
99
|
+
- spec/embedded_localization/native_column_spec.rb
|
100
|
+
- spec/embedded_localization/simple_model_spec.rb
|
101
|
+
- spec/models.rb
|
102
|
+
- spec/schema.rb
|
103
|
+
- spec/spec.opts
|
104
|
+
- spec/spec_helper.rb
|
37
105
|
homepage: http://www.unixgods.org/~tilo/Ruby/embedded_localization
|
38
|
-
licenses:
|
106
|
+
licenses:
|
39
107
|
- MIT
|
40
108
|
- GPL-2
|
41
|
-
metadata: {}
|
42
|
-
|
43
109
|
post_install_message:
|
44
110
|
rdoc_options: []
|
45
|
-
|
46
|
-
require_paths:
|
111
|
+
require_paths:
|
47
112
|
- lib
|
48
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version:
|
54
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
-
|
56
|
-
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
57
125
|
requirements: []
|
58
|
-
|
59
|
-
|
60
|
-
rubygems_version: 2.0.3
|
126
|
+
rubyforge_project: ! '[none]'
|
127
|
+
rubygems_version: 1.8.23
|
61
128
|
signing_key:
|
62
|
-
specification_version:
|
63
|
-
summary:
|
64
|
-
test_files:
|
65
|
-
|
129
|
+
specification_version: 3
|
130
|
+
summary: ! 'Rails I18n: library for embedded ActiveRecord 3 model/data translation'
|
131
|
+
test_files:
|
132
|
+
- spec/embedded_localization/native_column_spec.rb
|
133
|
+
- spec/embedded_localization/simple_model_spec.rb
|
134
|
+
- spec/models.rb
|
135
|
+
- spec/schema.rb
|
136
|
+
- spec/spec.opts
|
137
|
+
- spec/spec_helper.rb
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: fdcba308425918e44e09f1e8b3075144881eb5d8
|
4
|
-
data.tar.gz: f5104a299f3fd101b9841df6bd18ae2667deddc6
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 2cc84274a1080025f63a9064cc95ed7acbaf0258c0a8924a3b81eefd28ec3d0020c704055b3d715675cb35e6c81f323d884cde370f341d4d1ed06d3ee1439eb7
|
7
|
-
data.tar.gz: e9758eb1b84f98ef0c287f023a438b7d2bb8f6e2ade97aa4eea41baa04fa4d313520afe8568e1109d3235371988deaf9fa2bf7f7edfe36c97c2e02de61ea8eab
|