embedded_localization 0.2.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|