enumerations 2.0.0 → 2.1.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,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a75cec2684b73e9e83a7b60ddd48b95ac01fd991
4
- data.tar.gz: 822d8484b921612c31deadd8491994ad1e22a66d
3
+ metadata.gz: e9193bf66247b09a32a3a72da1257fe97890da52
4
+ data.tar.gz: b005aaba38109c814c7020e7053d31a56a6f98a3
5
5
  SHA512:
6
- metadata.gz: 3df5039cf8d021b312058982c26edee6d8e24c56bd05a4f9cba6db2f55adef3f311d3181a544e774cd3607750d0c813e4935fcbf3079608eec3a7a142a546d4d
7
- data.tar.gz: 04c31625eecf7f4276bf11d673aa66d2290ca086d49d728502cde004166a32c7a2ff051367356299feeee8399afc0b486551b00694b51fe47b69d1e72aaf05d1
6
+ metadata.gz: 2003c66e3f930f5b3fafd9eea13036159a0583694384a1c644566ca49150485516186dffa0a2191feac09064602f3a89af31607d7b3c7dab6adea3a589b71d02
7
+ data.tar.gz: de534b1cab979f08d362ce42ab61fbe2bf4851fb32da2adc4e1e1abd31a7274dd92b261488cb38402eee36ab4220fde052a357ba289fba2491be50879fa3627c
data/Readme.md CHANGED
@@ -47,7 +47,8 @@ Include enumerations for integer fields in other models:
47
47
  ```ruby
48
48
  class Post < ActiveRecord::Base
49
49
  enumeration :status
50
- validates :status_id, presence: true
50
+
51
+ validates :status, presence: true # You can validate either :status or :status_id
51
52
  end
52
53
  ```
53
54
 
@@ -58,7 +59,8 @@ class Post < ActiveRecord::Base
58
59
  enumeration :status,
59
60
  foreign_key: :post_status_id, # specifies which column to use
60
61
  class_name: Post::Status # specifies the class of the enumerator
61
- validates :post_status_id, presence: true
62
+
63
+ validates :post_status, presence: true
62
64
  end
63
65
  ```
64
66
  Attribute `foreign_key` you can pass as a `String` or a `Symbol`. Attribute `class_name` can be set as a `String`, a `Symbol` or a `String`.
@@ -120,17 +122,30 @@ end
120
122
  Find enumerations by `id`:
121
123
 
122
124
  ```ruby
123
- @post.status = Status.find(2) # => Review pending
125
+ @post.status = Status.find(2) # => Review pending
124
126
  @post.save
125
127
  ```
126
128
 
129
+ Other finding methods:
130
+
131
+ ```ruby
132
+ # Find by id as a String
133
+ Status.find('2') # => Review pending
134
+
135
+ # Find by symbol as a String
136
+ Status.find('draft') # => Draft
137
+
138
+ # Find by multiple attributes
139
+ Status.find_by(name: 'None', visible: true) # => None
140
+ ```
141
+
127
142
  Compare enumerations:
128
143
 
129
144
  ```ruby
130
- @post.status == :published # => true
131
- @post.status == 3 # => true
132
- @post.status == Status.find(:published) # => true
133
- @post.status.published? # => true
145
+ @post.status == :published # => true
146
+ @post.status == 3 # => true
147
+ @post.status == Status.find(:published) # => true
148
+ @post.status.published? # => true
134
149
  ```
135
150
 
136
151
  Get all enumerations:
@@ -141,6 +156,17 @@ Status.all
141
156
 
142
157
 
143
158
 
159
+ ## Filtering methods
160
+
161
+ Enumerations can be filtered with `where` method, similar to `ActiveRecord::QueryMethods#where`.
162
+
163
+ ```ruby
164
+ Role.where(admin: true) # => [Role.admin, Role.editor]
165
+ Role.where(admin: true, active: true) # => [Role.admin]
166
+ ```
167
+
168
+
169
+
144
170
  ## Scopes on model
145
171
 
146
172
  With enumerations, you'll get scope for each enumeration value in the
@@ -205,6 +231,36 @@ Status.review_pending.description # => 'Some description...'
205
231
  Status.draft.description # => nil
206
232
  ```
207
233
 
234
+ Translations
235
+ =====
236
+
237
+ **Enumerations** uses power of I18n API to enable you to create a locale file
238
+ for enumerations like this:
239
+
240
+ ```yaml
241
+ ---
242
+ en:
243
+ enumerations:
244
+ status:
245
+ draft:
246
+ name: Draft
247
+ description: Article draft...
248
+ ...
249
+ role:
250
+ admin:
251
+ name: Administrator
252
+ ```
253
+
254
+ > You can separate enumerations locales into a separate `*.yml` files.
255
+ > Then you should add locale file paths to I18n load path:
256
+
257
+ ```ruby
258
+ # config/initializers/locale.rb
259
+
260
+ # Where the I18n library should search for translation files (e.g.):
261
+ I18n.load_path += Dir[Rails.root.join('config', 'locales', 'enumerations', '*.yml')]
262
+ ```
263
+
208
264
  Author
209
265
  ======
210
266
 
@@ -12,6 +12,7 @@ Gem::Specification.new do |s|
12
12
 
13
13
  s.add_dependency 'activerecord'
14
14
  s.add_dependency 'activesupport'
15
+ s.add_dependency 'i18n'
15
16
  s.add_development_dependency 'pry-byebug'
16
17
  s.add_development_dependency 'rake'
17
18
  s.add_development_dependency 'codeclimate-test-reporter'
@@ -82,7 +82,7 @@ module Enumerations
82
82
  _values.values
83
83
  end
84
84
 
85
- attr_reader :symbol
85
+ attr_reader :symbol, :attributes
86
86
 
87
87
  def initialize(symbol, attributes)
88
88
  @symbol = symbol
@@ -17,6 +17,17 @@ module Enumerations
17
17
  end
18
18
  end
19
19
 
20
+ # Finds all enumerations which meets given attributes.
21
+ # Similar to ActiveRecord::QueryMethods#where.
22
+ #
23
+ # Example:
24
+ #
25
+ # Role.find_by(name: 'Admin') => #<Enumerations::Value: @base=Role, @symbol=:admin...>
26
+ #
27
+ def where(**args)
28
+ _values.values.select { |value| args.map { |k, v| value.attributes[k] == v }.all? }
29
+ end
30
+
20
31
  # Finds an enumeration by defined attribute. Similar to ActiveRecord::FinderMethods#find_by
21
32
  #
22
33
  # Example:
@@ -24,7 +35,7 @@ module Enumerations
24
35
  # Role.find_by(name: 'Admin') => #<Enumerations::Value: @base=Role, @symbol=:admin...>
25
36
  #
26
37
  def find_by(**args)
27
- _values.values.find { |value| args.map { |k, v| value.send(k) == v }.all? }
38
+ where(args).first
28
39
  end
29
40
 
30
41
  def find_by_key(key)
@@ -57,12 +57,21 @@ module Enumerations
57
57
  @attributes.each do |key, _|
58
58
  next if respond_to?(key)
59
59
 
60
- self.class.send :define_method, key do
61
- @attributes[key]
60
+ self.class.send :define_method, key do |locale: I18n.locale|
61
+ case @attributes[key]
62
+ when String, Symbol then translate_attribute(key, locale)
63
+ else @attributes[key]
64
+ end
62
65
  end
63
66
  end
64
67
  end
65
68
 
69
+ def translate_attribute(key, locale)
70
+ I18n.t(key, scope: [:enumerations, self.class.name.underscore, symbol],
71
+ default: @attributes[key],
72
+ locale: locale)
73
+ end
74
+
66
75
  # Predicate methods for values
67
76
  #
68
77
  # Example:
@@ -1,3 +1,3 @@
1
1
  module Enumerations
2
- VERSION = '2.0.0'
2
+ VERSION = '2.1.0'
3
3
  end
@@ -1,42 +1,6 @@
1
1
  require_relative 'test_helper'
2
2
 
3
3
  class BaseTest < Minitest::Test
4
- def test_lookup_by_symbol
5
- status = Status.find(:draft)
6
-
7
- assert_equal :draft, status.symbol
8
- end
9
-
10
- def test_lookup_fail_by_symbol
11
- status = Status.find(:draft)
12
-
13
- refute_same :published, status.symbol
14
- end
15
-
16
- def test_lookup_by_string_id
17
- status = Status.find('1')
18
-
19
- assert_equal :draft, status.symbol
20
- end
21
-
22
- def test_lookup_by_string_key
23
- status = Status.find('draft')
24
-
25
- assert_equal :draft, status.symbol
26
- end
27
-
28
- def test_find_by
29
- status = Status.find_by(name: 'Draft')
30
-
31
- assert_equal :draft, status.symbol
32
- end
33
-
34
- def test_fail_find_by
35
- status = Status.find_by(name: 'Draft1')
36
-
37
- assert_equal nil, status
38
- end
39
-
40
4
  def test_all
41
5
  statuses = Status.all
42
6
 
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/test_helper')
1
+ require_relative 'test_helper'
2
2
 
3
3
  class EnumerationsTest < Minitest::Test
4
4
  def test_reflect_on_all_enumerations
@@ -0,0 +1,71 @@
1
+ require_relative 'test_helper'
2
+
3
+ class FinderTest < Minitest::Test
4
+ def test_lookup_by_symbol
5
+ status = Status.find(:draft)
6
+
7
+ assert_equal :draft, status.symbol
8
+ end
9
+
10
+ def test_lookup_fail_by_symbol
11
+ status = Status.find(:draft)
12
+
13
+ refute_same :published, status.symbol
14
+ end
15
+
16
+ def test_lookup_by_string_id
17
+ status = Status.find('1')
18
+
19
+ assert_equal :draft, status.symbol
20
+ end
21
+
22
+ def test_lookup_by_string_key
23
+ status = Status.find('draft')
24
+
25
+ assert_equal :draft, status.symbol
26
+ end
27
+
28
+ def test_find_by
29
+ status = Status.find_by(name: 'Draft')
30
+
31
+ assert_equal :draft, status.symbol
32
+ end
33
+
34
+ def test_fail_find_by
35
+ status = Status.find_by(name: 'Draft1')
36
+
37
+ assert_equal nil, status
38
+ end
39
+
40
+ def test_where_by_name
41
+ statuses = Status.where(name: 'Draft')
42
+
43
+ assert_equal [Status.find(:draft)], statuses
44
+ end
45
+
46
+ def test_where_by_name_with_no_results
47
+ statuses = Status.where(name: 'Draft1')
48
+
49
+ assert_equal [], statuses
50
+ end
51
+
52
+ def test_where_by_custom_attributes
53
+ roles = Role.where(admin: true)
54
+
55
+ assert_equal 2, roles.count
56
+ assert_equal [:admin, :editor], roles.map(&:symbol)
57
+ end
58
+
59
+ def test_where_by_multiple_custom_attributes
60
+ roles = Role.where(admin: true, active: true)
61
+
62
+ assert_equal 1, roles.count
63
+ assert_equal [:admin], roles.map(&:symbol)
64
+ end
65
+
66
+ def test_where_by_undefined_custom_attributes
67
+ roles = Role.where(description1: false)
68
+
69
+ assert_equal [], roles
70
+ end
71
+ end
@@ -0,0 +1,4 @@
1
+ require 'i18n'
2
+
3
+ I18n.available_locales = [:en, :hr, :fr]
4
+ I18n.load_path = Dir[File.join('test', 'locales', '*.yml')]
@@ -0,0 +1,20 @@
1
+ ---
2
+ hr:
3
+ enumerations:
4
+ status:
5
+ draft:
6
+ name: Nacrt
7
+ review_pending:
8
+ name: Čeka pregled
9
+ published:
10
+ name: Published
11
+
12
+ role:
13
+ admin:
14
+ name: Admin
15
+ editor:
16
+ name: Urednik
17
+ description: Uređuje novine
18
+ author:
19
+ name: Autor
20
+ description: Autor novina
@@ -6,20 +6,21 @@ require 'enumerations'
6
6
  require 'active_record'
7
7
  require 'pry'
8
8
 
9
- require_relative 'database_helper'
9
+ require_relative 'helpers/database_helper'
10
+ require_relative 'helpers/locale_helper'
10
11
 
11
12
  class Status < Enumerations::Base
12
13
  values draft: { id: 1, name: 'Draft' },
13
14
  review_pending: { id: 2, name: 'Review pending' },
14
15
  published: { id: 3, name: 'Published' }
15
16
 
16
- value :none, id: 4, name: 'None', visible: true
17
+ value :none, id: 4, name: 'None', visible: true, deleted: false
17
18
  value :deleted, id: 5, deleted: true
18
19
  end
19
20
 
20
21
  class Role < Enumerations::Base
21
- value :admin, id: 1, name: 'Admin', admin: true
22
- value :editor, id: 2, name: 'Editor'
22
+ value :admin, id: 1, name: 'Admin', admin: true, active: true
23
+ value :editor, id: 2, name: 'Editor', admin: true, active: false, description: 'Edits newspapers'
23
24
  value :author, id: 3, name: 'Author'
24
25
 
25
26
  def my_custom_name
@@ -0,0 +1,94 @@
1
+ require_relative 'test_helper'
2
+
3
+ class TranslationTest < Minitest::Test
4
+ def test_translated_value_with_default_locale
5
+ status = Status.find(:draft)
6
+
7
+ assert_equal 'Draft', status.name
8
+ end
9
+
10
+ def test_translated_value_with_i18n_locale
11
+ status = Status.find(:draft)
12
+
13
+ I18n.locale = :hr
14
+ translated_name = status.name
15
+ I18n.locale = :en
16
+
17
+ assert_equal 'Nacrt', translated_name
18
+ end
19
+
20
+ def test_translated_value_with_i18n_locales
21
+ status = Status.find(:draft)
22
+
23
+ I18n.locale = :hr
24
+ assert_equal 'Nacrt', status.name
25
+ I18n.locale = :en
26
+ assert_equal 'Draft', status.name
27
+ end
28
+
29
+ def test_translated_value_with_custom_locale
30
+ status = Status.find(:draft)
31
+
32
+ assert_equal 'Nacrt', status.name(locale: :hr)
33
+ end
34
+
35
+ def test_boolean_value_true_not_changed_by_translations
36
+ status = Status.find(:none)
37
+
38
+ assert_equal true, status.visible
39
+ end
40
+
41
+ def test_boolean_value_false_not_changed_by_translations
42
+ status = Status.find(:none)
43
+
44
+ assert_equal false, status.deleted
45
+ end
46
+
47
+ def test_boolean_value_false_not_changed_by_translations_with_custom_locale
48
+ status = Status.find(:none)
49
+
50
+ assert_equal false, status.deleted(locale: :hr)
51
+ end
52
+
53
+ def test_translated_custom_attribute_with_i18n_locale
54
+ role = Role.find(:editor)
55
+
56
+ I18n.locale = :hr
57
+ translated_value = role.description
58
+ I18n.locale = :en
59
+
60
+ assert_equal 'Uređuje novine', translated_value
61
+ end
62
+
63
+ def test_translated_custom_attribute_with_custom_locale
64
+ role = Role.find(:editor)
65
+
66
+ assert_equal 'Uređuje novine', role.description(locale: :hr)
67
+ end
68
+
69
+ def test_empty_custom_attribute_with_custom_locale
70
+ role = Role.find(:admin)
71
+
72
+ assert_equal nil, role.description(locale: :hr)
73
+ end
74
+
75
+ def test_empty_custom_attribute_with_custom_locale_and_defined_translation
76
+ role = Role.find(:author)
77
+
78
+ assert_equal nil, role.description(locale: :hr)
79
+ end
80
+
81
+ def test_find_by_localized_name
82
+ status = Status.find_by(name: 'Draft')
83
+
84
+ assert_equal :draft, status.symbol
85
+ end
86
+
87
+ def test_find_by_localized_name_with_i18n_locale
88
+ I18n.locale = :hr
89
+ status = Status.find_by(name: 'Nacrt')
90
+ I18n.locale = :en
91
+
92
+ assert_equal nil, status
93
+ end
94
+ end
@@ -2,6 +2,6 @@ require_relative 'test_helper'
2
2
 
3
3
  class VersionTest < Minitest::Test
4
4
  def test_version
5
- assert_equal '2.0.0', Enumerations::VERSION
5
+ assert_equal '2.1.0', Enumerations::VERSION
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enumerations
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomislav Car
@@ -40,6 +40,20 @@ dependencies:
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
42
  version: '0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: i18n
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
43
57
  - !ruby/object:Gem::Dependency
44
58
  name: pry-byebug
45
59
  requirement: !ruby/object:Gem::Requirement
@@ -117,10 +131,14 @@ files:
117
131
  - lib/enumerations/value.rb
118
132
  - lib/enumerations/version.rb
119
133
  - test/base_test.rb
120
- - test/database_helper.rb
121
134
  - test/enumerations_test.rb
135
+ - test/finder_test.rb
136
+ - test/helpers/database_helper.rb
137
+ - test/helpers/locale_helper.rb
138
+ - test/locales/hr.yml
122
139
  - test/reflection_test.rb
123
140
  - test/test_helper.rb
141
+ - test/translation_test.rb
124
142
  - test/value_test.rb
125
143
  - test/version_test.rb
126
144
  homepage: https://github.com/infinum/enumerations
@@ -148,9 +166,13 @@ specification_version: 4
148
166
  summary: Enumerations for ActiveRecord!
149
167
  test_files:
150
168
  - test/base_test.rb
151
- - test/database_helper.rb
152
169
  - test/enumerations_test.rb
170
+ - test/finder_test.rb
171
+ - test/helpers/database_helper.rb
172
+ - test/helpers/locale_helper.rb
173
+ - test/locales/hr.yml
153
174
  - test/reflection_test.rb
154
175
  - test/test_helper.rb
176
+ - test/translation_test.rb
155
177
  - test/value_test.rb
156
178
  - test/version_test.rb