traco 3.2.1 → 5.3.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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- OTY3M2RiMzgxNzI2YzY5YWQ2Nzg5N2VhMmY0ZDg0YjlhOGQwMzQ1Ng==
5
- data.tar.gz: !binary |-
6
- MTI3YWIxYmRjNDQ5MmIxNWIyNmI3NGFjMWEwY2FiZWEwMjNiMWFiOA==
2
+ SHA256:
3
+ metadata.gz: c8d3d3ad540b0b54d9a5ce5adb2128e2edb4f3a1639cc943005bf8f0ffc59046
4
+ data.tar.gz: 28ac1c659ba7e3b6160e5d7da6bd995a2a0a12c08b0e070d461b45b85cc751ae
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MGZjNTUyNzg3NDNiOWQyYjM2ZTE4NmRhOGY5Mzc3ZGJlY2ZkOWZiYzJjMTVm
10
- OTA3ZDY1ZWMxZDFmMmFkMGM4NTE4Y2I0ZjM1NTY2ODFmY2UwMzY0ZjYwZTQy
11
- YWM1N2U2OTkyNWY3YTM1OTU2NDNlMjNlNjczMTBjYmZjMzU2Yzk=
12
- data.tar.gz: !binary |-
13
- OTUyOGE2M2E0MTM3ODVhMjg1MTA3MDkzNDU3YmUwOTZhMWM5Yjg0MDJhNDU2
14
- YzVjM2JhM2E3ZjBhOWJmZTUzOWI2NWIxZTljZjA4MDUxMWUyMzkyMTUyNmI5
15
- NmRiOTdhNzA2NmU3OTVmZmM2N2U3MWQzN2NiMmIyOGUyOTU5MDg=
6
+ metadata.gz: d2bd0a863da9ad824af47836f419f0b89ffd366aebf45a05772c2d109249effde7f5f18904480da34fd7d4deaf338125cfc5e8a74926c24ea6eecac8a16419dd
7
+ data.tar.gz: 6604dbef3ea352ecb532aa77b826e15664cb407bf168240d254f194b0be9340ced3791eda23d45199d14860c8a0f3364bb78c3d0ef257a0a9d565f3d8bb90a29
@@ -7,6 +7,7 @@ module Traco
7
7
  attributes.each do |attribute|
8
8
  define_reader(attribute)
9
9
  define_writer(attribute)
10
+ define_query(attribute)
10
11
  end
11
12
  end
12
13
 
@@ -20,12 +21,13 @@ module Traco
20
21
  private
21
22
 
22
23
  def define_reader(attribute)
24
+ default_fallback = @options.fetch(:fallback, LocaleFallbacks::DEFAULT_FALLBACK)
25
+
23
26
  class_eval <<-EOM, __FILE__, __LINE__ + 1
24
- def #{attribute}(options = {})
25
- default_fallback = #{@options.fetch(:fallback, LocaleFallbacks::DEFAULT_FALLBACK).inspect}
26
- fallback = options.fetch(:fallback, default_fallback)
27
+ def #{attribute}(locale: nil, fallback: #{default_fallback.inspect})
28
+ return send(Traco.column(:#{attribute}, locale)) if locale
27
29
 
28
- columns_to_try = self.class._locale_columns_for_attribute(:#{attribute}, fallback)
30
+ columns_to_try = self.class._locale_columns_for_attribute(:#{attribute}, fallback: fallback)
29
31
  columns_to_try.each do |column|
30
32
  value = send(column)
31
33
  return value if value.present?
@@ -45,6 +47,14 @@ module Traco
45
47
  EOM
46
48
  end
47
49
 
50
+ def define_query(attribute)
51
+ class_eval <<-EOM, __FILE__, __LINE__ + 1
52
+ def #{attribute}?(locale: nil)
53
+ send(:#{attribute}, locale: locale).present?
54
+ end
55
+ EOM
56
+ end
57
+
48
58
  # Only called once per class or inheritance chain (e.g. once
49
59
  # for the superclass, not at all for subclasses). The separation
50
60
  # is important if we don't want to overwrite values if running
@@ -1,18 +1,20 @@
1
1
  module Traco
2
2
  module ClassMethods
3
3
  def locales_for_attribute(attribute)
4
- traco_cache(attribute, LocaleFallbacks::DEFAULT_FIRST_FALLBACK).keys
4
+ traco_cache(attribute, fallback: LocaleFallbacks::ANY_FALLBACK).keys
5
5
  end
6
6
 
7
7
  def locale_columns(*attributes)
8
- attributes.each_with_object([]) do |attribute, columns|
9
- columns.concat(_locale_columns_for_attribute(attribute, LocaleFallbacks::DEFAULT_FIRST_FALLBACK))
10
- end
8
+ attributes = attributes.presence || translatable_attributes
9
+
10
+ attributes.flat_map { |attribute|
11
+ _locale_columns_for_attribute(attribute, fallback: LocaleFallbacks::ANY_FALLBACK)
12
+ }
11
13
  end
12
14
 
13
15
  # Consider this method internal.
14
- def _locale_columns_for_attribute(attribute, fallback)
15
- traco_cache(attribute, fallback).values
16
+ def _locale_columns_for_attribute(attribute, fallback:)
17
+ traco_cache(attribute, fallback: fallback).values
16
18
  end
17
19
 
18
20
  def current_locale_column(attribute)
@@ -52,7 +54,7 @@ module Traco
52
54
  # }
53
55
  # }
54
56
  # }
55
- def traco_cache(attribute, fallback)
57
+ def traco_cache(attribute, fallback:)
56
58
  cache = @traco_cache ||= {}
57
59
  per_locale_cache = cache[I18n.locale] ||= {}
58
60
  per_attribute_cache = per_locale_cache[attribute] ||= {}
@@ -7,6 +7,7 @@ module Traco
7
7
  ANY_FALLBACK = :any,
8
8
  NO_FALLBACK = false,
9
9
  DEFAULT_FIRST_FALLBACK = :default_first,
10
+ I18N_FALLBACK = :i18n,
10
11
  ]
11
12
 
12
13
  attr_reader :fallback_option
@@ -26,6 +27,7 @@ module Traco
26
27
  when ANY_FALLBACK then [ current_locale, @default_locale, *@available_locales ].uniq
27
28
  when NO_FALLBACK then [ current_locale ]
28
29
  when DEFAULT_FIRST_FALLBACK then [ @default_locale, *@available_locales ].uniq
30
+ when I18N_FALLBACK then I18n.fallbacks[current_locale]
29
31
  when Array then [ current_locale, *fallback_option ]
30
32
  else raise "Unknown fallback." # Should never get here.
31
33
  end
data/lib/traco/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Traco
2
- VERSION = "3.2.1"
2
+ VERSION = "5.3.0"
3
3
  end
@@ -1,7 +1,6 @@
1
- require "spec_helper"
2
1
  require "traco/locale_fallbacks"
3
2
 
4
- describe Traco::LocaleFallbacks do
3
+ RSpec.describe Traco::LocaleFallbacks do
5
4
  describe ".new" do
6
5
  it "raises ArgumentError if an unknown argument passed in" do
7
6
  expect { Traco::LocaleFallbacks.new(:foo) }.to raise_error(ArgumentError)
@@ -51,5 +50,20 @@ describe Traco::LocaleFallbacks do
51
50
  expect(subject[:sv]).to eq [ :uk, :de, :en, :sv ]
52
51
  end
53
52
  end
53
+
54
+ context "with the ':i18n' option" do
55
+ it "returns what is configured as a I18n fallback" do
56
+ I18n.fallbacks = I18n::Locale::Fallbacks.new(
57
+ en: [ :en, :uk, :de, :sv ],
58
+ uk: [ :uk, :en, :de, :sv ],
59
+ de: [ :de, :uk, :en, :sv ],
60
+ sv: [ :sv, :en, :uk, :de ],
61
+ )
62
+
63
+ subject = Traco::LocaleFallbacks.new(:i18n)
64
+ expect(subject[:sv]).to eq [ :sv, :en, :uk, :de ]
65
+ expect(subject[:de]).to eq [ :de, :uk, :en, :sv ]
66
+ end
67
+ end
54
68
  end
55
69
  end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  require "i18n"
2
2
 
3
3
  RSpec.configure do |config|
4
- config.treat_symbols_as_metadata_keys_with_true_values = true
5
4
  config.filter_run focus: true
6
5
  config.run_all_when_everything_filtered = true
6
+ config.disable_monkey_patching!
7
7
  end
8
8
 
9
9
  I18n.enforce_available_locales = false
10
+
11
+ I18n::Backend::Simple.include(I18n::Backend::Fallbacks)
@@ -1,5 +1,5 @@
1
1
  RSpec.configure do |config|
2
- config.before(:each) do
2
+ config.before do
3
3
  # Clear class state before each spec.
4
4
  Object.send(:remove_const, "Post")
5
5
  Object.send(:remove_const, "SubPost")
@@ -19,12 +19,10 @@ require "app/post.rb"
19
19
 
20
20
  ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
21
21
 
22
- silence_stream(STDOUT) do
23
- ActiveRecord::Schema.define(version: 0) do
24
- create_table :posts, force: true do |t|
25
- t.string :title_sv, :title_en, :title_pt_br
26
- t.string :body_sv, :body_en, :body_pt_br
27
- end
22
+ ActiveRecord::Schema.define(version: 0) do
23
+ create_table :posts, force: true do |t|
24
+ t.string :title_sv, :title_en, :title_pt_br, :title_de
25
+ t.string :body_sv, :body_en, :body_pt_br, :body_de
28
26
  end
29
27
  end
30
28
 
data/spec/traco_spec.rb CHANGED
@@ -1,10 +1,9 @@
1
1
  # encoding: utf-8
2
2
 
3
- require "spec_helper"
4
3
  require "spec_helper_models"
5
4
  require "traco"
6
5
 
7
- describe Traco, ".split_localized_column" do
6
+ RSpec.describe Traco, ".split_localized_column" do
8
7
  subject { described_class }
9
8
 
10
9
  it "returns attribute and locale" do
@@ -24,7 +23,7 @@ describe Traco, ".split_localized_column" do
24
23
  end
25
24
  end
26
25
 
27
- describe ActiveRecord::Base, ".translates" do
26
+ RSpec.describe ActiveRecord::Base, ".translates" do
28
27
  it "is available" do
29
28
  expect(Post).to respond_to :translates
30
29
  end
@@ -57,7 +56,7 @@ describe ActiveRecord::Base, ".translates" do
57
56
  end
58
57
  end
59
58
 
60
- describe Post, ".translatable_attributes" do
59
+ RSpec.describe Post, ".translatable_attributes" do
61
60
  before do
62
61
  Post.translates :title
63
62
  end
@@ -77,15 +76,15 @@ describe Post, ".translatable_attributes" do
77
76
  end
78
77
  end
79
78
 
80
- describe Post, ".locales_for_attribute" do
79
+ RSpec.describe Post, ".locales_for_attribute" do
81
80
  before do
82
81
  Post.translates :title
83
82
  I18n.default_locale = :"pt-BR"
84
83
  I18n.locale = :en
85
84
  end
86
85
 
87
- it "lists the locales for that attribute, default locale first and then alphabetically" do
88
- expect(Post.locales_for_attribute(:title)).to eq [ :"pt-BR", :en, :sv ]
86
+ it "lists the locales for that attribute, current locale first, then default locale, and then alphabetically" do
87
+ expect(Post.locales_for_attribute(:title)).to eq [ :en, :"pt-BR", :de, :sv ]
89
88
  end
90
89
 
91
90
  it "doesn't include a locale if there's no corresponding column for it" do
@@ -95,16 +94,16 @@ describe Post, ".locales_for_attribute" do
95
94
  end
96
95
  end
97
96
 
98
- describe Post, ".locale_columns" do
97
+ RSpec.describe Post, ".locale_columns" do
99
98
  before do
100
99
  Post.translates :title
101
100
  I18n.default_locale = :"pt-BR"
102
101
  I18n.locale = :en
103
102
  end
104
103
 
105
- it "lists the columns-with-locale for that attribute, default locale first and then alphabetically" do
104
+ it "lists the columns-with-locale for that attribute, current locale first, then default locale, and then alphabetically" do
106
105
  expect(Post.locale_columns(:title)).to eq [
107
- :title_pt_br, :title_en, :title_sv
106
+ :title_en, :title_pt_br, :title_de, :title_sv,
108
107
  ]
109
108
  end
110
109
 
@@ -118,13 +117,19 @@ describe Post, ".locale_columns" do
118
117
  Post.translates :body
119
118
 
120
119
  expect(Post.locale_columns(:body, :title)).to eq [
121
- :body_pt_br, :body_en, :body_sv,
122
- :title_pt_br, :title_en, :title_sv,
120
+ :body_en, :body_pt_br, :body_de, :body_sv,
121
+ :title_en, :title_pt_br, :title_de, :title_sv,
122
+ ]
123
+ end
124
+
125
+ it "returns the columns of all translated attributes if no params are supplied" do
126
+ expect(Post.locale_columns).to eq [
127
+ :title_en, :title_pt_br, :title_de, :title_sv
123
128
  ]
124
129
  end
125
130
  end
126
131
 
127
- describe Post, ".current_locale_column" do
132
+ RSpec.describe Post, ".current_locale_column" do
128
133
  before do
129
134
  Post.translates :title
130
135
  end
@@ -140,7 +145,7 @@ describe Post, ".current_locale_column" do
140
145
  end
141
146
  end
142
147
 
143
- describe Post, "#title" do
148
+ RSpec.describe Post, "#title" do
144
149
  let(:post) {
145
150
  Post.new(title_sv: "Hej", title_en: "Halloa", title_pt_br: "Olá")
146
151
  }
@@ -225,6 +230,19 @@ describe Post, "#title" do
225
230
  expect(post.title).to eq "Hej"
226
231
  end
227
232
 
233
+ context "when given a 'locale' argument" do
234
+ it "gives the title in that locale, without fallback" do
235
+ post = Post.new(title_sv: "Hej", title_en: "Halloa")
236
+ I18n.default_locale = :en
237
+ I18n.locale = :en
238
+
239
+ expect(post.title(locale: :sv)).to eq "Hej"
240
+
241
+ post.title_sv = nil
242
+ expect(post.title(locale: :sv)).to eq nil
243
+ end
244
+ end
245
+
228
246
  context "when the translation was defined with fallback: false" do
229
247
  let(:post) {
230
248
  Post.new(title_sv: "Hej", title_en: "Halloa")
@@ -271,7 +289,7 @@ describe Post, "#title" do
271
289
  end
272
290
  end
273
291
 
274
- describe Post, "#title=" do
292
+ RSpec.describe Post, "#title=" do
275
293
  before do
276
294
  Post.translates :title
277
295
  end
@@ -298,7 +316,37 @@ describe Post, "#title=" do
298
316
  end
299
317
  end
300
318
 
301
- describe Post, ".human_attribute_name" do
319
+ RSpec.describe Post, "#title?" do
320
+ before do
321
+ Post.translates :title
322
+ I18n.locale = :sv
323
+ I18n.default_locale = :en
324
+ end
325
+
326
+ it "is true if the title is present, with fallback" do
327
+ post = Post.new(title_sv: "", title_en: " ", title_pt_br: nil)
328
+ expect(post.title?).to be false
329
+
330
+ post.title_en = "Hello"
331
+
332
+ expect(post.title?).to be true
333
+ end
334
+
335
+ context "when given a 'locale' argument" do
336
+ it "is true if the title if present in that locale, with no fallback" do
337
+ post = Post.new(title_sv: "Hej", title_en: "Halloa")
338
+ I18n.default_locale = :en
339
+ I18n.locale = :en
340
+
341
+ expect(post.title?(locale: :sv)).to be true
342
+
343
+ post.title_sv = nil
344
+ expect(post.title?(locale: :sv)).to be false
345
+ end
346
+ end
347
+ end
348
+
349
+ RSpec.describe Post, ".human_attribute_name" do
302
350
  before do
303
351
  Post.translates :title
304
352
  I18n.locale = :sv
metadata CHANGED
@@ -1,87 +1,93 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: traco
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.1
4
+ version: 5.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henrik Nyh
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-14 00:00:00.000000000 Z
11
+ date: 2021-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '4.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '3.0'
26
+ version: '4.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sqlite3
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description:
69
+ - !ruby/object:Gem::Dependency
70
+ name: appraisal
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
70
84
  email:
71
85
  - henrik@barsoom.se
72
86
  executables: []
73
87
  extensions: []
74
88
  extra_rdoc_files: []
75
89
  files:
76
- - .gitignore
77
- - .rvmrc
78
- - .travis.yml
79
- - CHANGELOG.md
80
- - Gemfile
81
90
  - LICENSE.txt
82
- - README.md
83
- - Rakefile
84
- - benchmarks/overhead.rb
85
91
  - lib/traco.rb
86
92
  - lib/traco/attributes.rb
87
93
  - lib/traco/class_methods.rb
@@ -94,35 +100,33 @@ files:
94
100
  - spec/spec_helper.rb
95
101
  - spec/spec_helper_models.rb
96
102
  - spec/traco_spec.rb
97
- - traco.gemspec
98
103
  homepage: ''
99
104
  licenses:
100
105
  - MIT
101
106
  metadata: {}
102
- post_install_message:
107
+ post_install_message:
103
108
  rdoc_options: []
104
109
  require_paths:
105
110
  - lib
106
111
  required_ruby_version: !ruby/object:Gem::Requirement
107
112
  requirements:
108
- - - ! '>='
113
+ - - ">="
109
114
  - !ruby/object:Gem::Version
110
- version: '0'
115
+ version: 2.3.0
111
116
  required_rubygems_version: !ruby/object:Gem::Requirement
112
117
  requirements:
113
- - - ! '>='
118
+ - - ">="
114
119
  - !ruby/object:Gem::Version
115
120
  version: '0'
116
121
  requirements: []
117
- rubyforge_project:
118
- rubygems_version: 2.2.2
119
- signing_key:
122
+ rubygems_version: 3.1.4
123
+ signing_key:
120
124
  specification_version: 4
121
- summary: Translatable columns for Rails 3 or better, stored in the model table itself.
125
+ summary: Translatable columns for Rails 4.2 or better, stored in the model table itself.
122
126
  test_files:
123
- - spec/app/post.rb
124
- - spec/app/sv.yml
125
- - spec/locale_fallbacks_spec.rb
126
127
  - spec/spec_helper.rb
127
- - spec/spec_helper_models.rb
128
+ - spec/app/sv.yml
129
+ - spec/app/post.rb
128
130
  - spec/traco_spec.rb
131
+ - spec/spec_helper_models.rb
132
+ - spec/locale_fallbacks_spec.rb
data/.gitignore DELETED
@@ -1,5 +0,0 @@
1
- .bundle/
2
- Gemfile.lock
3
- pkg/
4
- tmp
5
- *.gem
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm ruby-1.9.3-p194-falcon@traco --create
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.1.0
4
- - 2.0.0
5
- - 1.9.3
data/CHANGELOG.md DELETED
@@ -1,59 +0,0 @@
1
- # Changelog
2
-
3
- ## 3.2.1
4
-
5
- * Bugfix: with `fallback: [:sv]`, always look at current locale before any fallbacks.
6
-
7
- ## 3.2.0
8
-
9
- * Introduce e.g. `fallback: [:sv]` to explicitly specify fallbacks.
10
-
11
- ## 3.1.6
12
-
13
- Make [license (MIT)](LICENSE.txt) easier to autodetect.
14
-
15
- ## 3.1.5
16
-
17
- * Bugfix: don't raise error loading models before the DB is created. Thanks to PikachuEXE and Andrii Malyshko.
18
-
19
- ## 3.1.4
20
-
21
- * Bugfix: restore sorting of `locale_columns` and `locales_for_attribute` to put default locale first, not current locale. Thanks to PikachuEXE.
22
-
23
- ## 3.1.3
24
-
25
- * ~20 time speedup thanks to optimizations by Andrii Malyshko.
26
-
27
- Reading a Traco translated attribute used to be ~250x slower than an untranslated attribute; now it's down to ~10x slower.
28
-
29
- ## 3.1.2
30
-
31
- * Bugfix: `.current_locale_column` handles dashed locales like "pt-BR" correctly. Thanks to PikachuEXE.
32
-
33
- ## 3.1.1
34
-
35
- * Bugfix around fallbacks and memoization. Thanks to PikachuEXE.
36
-
37
- ## 3.1.0
38
-
39
- * Introduce `.current_locale_column`, e.g. `Post.current_locale_column(:title) # => :title_sv`.
40
-
41
- ## 3.0.0
42
-
43
- * Backwards incompatible: `fallback: true` is now `fallback: :default`. Since this was the implicit default value, you shouldn't have a problem unless you explicitly declared this value.
44
-
45
- ## 2.2.0
46
-
47
- * `fallback: :any` to fall back to any other locale if the text is blank in the current and default locales.
48
-
49
- ## 2.1.0
50
-
51
- * Attribute readers can override the attribute's `fallback` setting, e.g. `item.title(fallback: false)`.
52
-
53
- ## 2.0.0
54
-
55
- * Backwards incompatible: for dashed locales like "pt-BR", the column names are now expected to end in e.g. `_pt_br`, not `_pt-BR`.
56
-
57
- ## 1.3.0
58
-
59
- Whatever we had before introducing this changelog.
data/Gemfile DELETED
@@ -1,8 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in the .gemspec.
4
- gemspec
5
-
6
- group :benchmark do
7
- gem "benchmark-ips"
8
- end
data/README.md DELETED
@@ -1,174 +0,0 @@
1
- # Traco
2
-
3
- [![Build Status](https://secure.travis-ci.org/barsoom/traco.png)](http://travis-ci.org/barsoom/traco)
4
-
5
- Translatable attributes for Rails 3 and 4 (Ruby 1.9+), stored in the model table itself.
6
-
7
- Inspired by Iain Hecker's [translatable_columns](https://github.com/iain/translatable_columns/).
8
-
9
- To store translations outside the model, see Sven Fuchs' [Globalize](https://github.com/globalize/globalize).
10
-
11
-
12
- ## Usage
13
-
14
- Say you want `Post#title` and `Post#body` to support both English and Swedish values.
15
-
16
- Write a migration to get database columns with locale suffixes, e.g. `title_sv` and `title_en`, like:
17
-
18
- ```ruby
19
- class CreatePosts < ActiveRecord::Migration
20
- def change
21
- create_table :posts do |t|
22
- t.string :title_sv, :title_en
23
- t.text :body_sv, :body_en
24
-
25
- t.timestamps
26
- end
27
- end
28
- end
29
- ```
30
-
31
- Don't create a database column named `title` without a suffix, since Traco will define a method with that name.
32
-
33
- If you use a locale format like `pt-BR`, the column name would be `title_pt_br`.
34
-
35
- Declare the attributes in the model:
36
-
37
- ```ruby
38
- class Post < ActiveRecord::Base
39
- translates :title, :body
40
- end
41
- ```
42
-
43
- You can still use your accessors like `title_sv` and `title_sv=` in forms, validations and other code, but you also get:
44
-
45
- `#title`: Shows the title in the current locale. If blank, falls back to default locale. Otherwise nil.
46
-
47
- `#title=`: Assigns the title to the column for the current locale, if present. Raises if the column doesn't exist.
48
-
49
- `.human_attribute_name(:title_sv)`: Extends this standard method to return "Title (Swedish)" if you have a translation key `i18n.languages.sv = "Swedish"` and "Title (SV)" otherwise. Rails uses this method to build validation error messages and form labels.
50
-
51
- `.translatable_attributes`: Returns an array like `[:title, :body]`.
52
-
53
- `.locale_columns(:title)`: Returns an array like `[:title_sv, :title_en]` sorted with default locale first and then alphabetically. Suitable for looping in forms:
54
-
55
- ```erb
56
- <% Post.locale_columns(:title).each do |column| %>
57
- <p>
58
- <%= form.label column %>
59
- <%= form.text_field column %>
60
- </p>
61
- <% end %>
62
- ```
63
-
64
- Or perhaps for things like:
65
-
66
- ```ruby
67
- attr_accessible *locale_columns(:title)
68
-
69
- validates *locale_columns(:title), :uniqueness => true
70
- ```
71
-
72
- You can also pass multiple attributes if you like:
73
-
74
- ```ruby
75
- attr_accessible *locale_columns(:title, :body)
76
- ```
77
-
78
- The return value will be sorted like `[:title_sv, :title_en, :body_sv, :body_en]`.
79
-
80
- `.current_locale_column(:title)`: Returns `:title_sv` if `:sv` is the current locale. Suitable for some SQL queries, such as sorting.
81
-
82
- `.locales_for_attribute(:title)`: Returns an array like `[:sv, :en]` sorted with default locale first and then alphabetically.
83
-
84
- And the equivalent methods for `body`, of course.
85
-
86
- Please note that your `translates :title, :body` declaration must be called before you call `locale_columns`. Otherwise you will get an error like "NoMethodError: undefined method `locale\_columns' for #\<Class:0x00000003f69188\>".
87
-
88
-
89
- ### Fallbacks
90
-
91
- By default, Traco will fall back to the default locale if there is no translation in the current locale.
92
-
93
- You can specify e.g. `translates :title, fallback: false` to never fall back and instead return `nil`.
94
-
95
- You can specify e.g. `translates :title, fallback: :any` to fall back first to the default locale, then to any other locale.
96
-
97
- You can specify e.g. `translates :title, fallback: [:sv]` to explicitly declare fallbacks as an array of any length.
98
-
99
- You can override the default fallback strategy with a parameter passed to the reader: `post.title(fallback: :any)`.
100
-
101
- If you need to declare the default locale fallback, do `post.title(fallback: :default)`.
102
-
103
-
104
- ### Overriding methods
105
-
106
- Methods are defined in an included module, so you can just override them and call Traco's implementation with `super`:
107
-
108
- ```ruby
109
- class Post < ActiveRecord::Base
110
- translates :title
111
-
112
- def title
113
- super.reverse
114
- end
115
- end
116
- ```
117
-
118
- ## Installation
119
-
120
- Add this to your `Gemfile`:
121
-
122
- ```ruby
123
- gem 'traco'
124
- ```
125
-
126
- Then run
127
-
128
- bundle
129
-
130
- to install it.
131
-
132
-
133
- ## Running the tests
134
-
135
- bundle
136
- rake
137
-
138
-
139
- ## Benchmark
140
-
141
- ruby benchmarks/overhead.rb
142
-
143
-
144
- <!-- Keeping this a hidden brain dump for now.
145
-
146
- ## TODO
147
-
148
- We've intentionally kept this simple with no features we do not need.
149
- We'd be happy to merge additional features that others contribute.
150
-
151
- Possible improvements to make:
152
-
153
- * Validation that checks that at least one translation for a column exists.
154
- * Validation that checks that every translation for a column exists.
155
- * Scopes like `translated`, `translated_to(locale)`.
156
- * Support for region locales, like `en-US` and `en-GB`.
157
-
158
- -->
159
-
160
- ## Contributors
161
-
162
- * [Henrik Nyh](http://henrik.nyh.se)
163
- * Andrii Malyshko
164
- * Tobias Bohwalli
165
- * Mario Alberto Chavez
166
- * Philip Arndt
167
- * [PikachuEXE](https://github.com/PikachuEXE)
168
- * Fernando Morgenstern
169
- * Tomáš Horáček
170
- * Joakim Kolsjö
171
-
172
- ## License
173
-
174
- [MIT](LICENSE.txt)
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task :default => :spec
@@ -1,41 +0,0 @@
1
- # This benchmark tests how fast a Traco-wrapped attribute is
2
- # compared to the plain Active Record attribute.
3
-
4
- require "bundler/setup"
5
- require "benchmark/ips"
6
- require "active_record"
7
- require "traco"
8
-
9
- ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
10
-
11
- I18n.enforce_available_locales = false
12
- I18n.available_locales = [ :en, :de, :sv ]
13
- I18n.default_locale = :en
14
- I18n.locale = :sv
15
-
16
- COLUMNS = %w(title body long_title seo_title)
17
-
18
- silence_stream(STDOUT) do
19
- ActiveRecord::Schema.define(version: 0) do
20
- create_table :posts, force: true do |t|
21
- I18n.available_locales.each do |locale|
22
- COLUMNS.each do |column|
23
- t.string "#{column}_#{locale}"
24
- end
25
- end
26
- end
27
- end
28
- end
29
-
30
- class Post < ActiveRecord::Base
31
- translates *COLUMNS
32
- end
33
-
34
- post = Post.new(title_en: "hello", title_sv: "Hej")
35
-
36
- Benchmark.ips do |x|
37
- x.report("activerecord") { post.title_sv }
38
- x.report("traco") { post.title }
39
-
40
- x.compare!
41
- end
data/traco.gemspec DELETED
@@ -1,25 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "traco/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "traco"
7
- s.version = Traco::VERSION
8
- s.authors = ["Henrik Nyh"]
9
- s.email = ["henrik@barsoom.se"]
10
- s.homepage = ""
11
- s.summary = "Translatable columns for Rails 3 or better, stored in the model table itself."
12
- s.license = "MIT"
13
-
14
- s.files = `git ls-files`.split("\n")
15
- s.test_files = `git ls-files -- spec/*`.split("\n")
16
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
- s.require_paths = ["lib"]
18
-
19
- s.add_dependency "activerecord", ">= 3.0"
20
-
21
- s.add_development_dependency "sqlite3"
22
-
23
- s.add_development_dependency "rake"
24
- s.add_development_dependency "rspec"
25
- end