enumerations 2.0.0 → 2.1.0

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