enum_accessor 1.1.0 → 2.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.
- checksums.yaml +4 -4
- data/README.md +14 -6
- data/lib/enum_accessor.rb +27 -33
- data/lib/enum_accessor/version.rb +1 -1
- data/spec/enum_accessor_spec.rb +7 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14d9609313d6c0cf506e0ddec8e2e1b040f0f0a4
|
4
|
+
data.tar.gz: 55f3e47cc0ad9fc6a638428ffeae93d820c556a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38379123736f3948c01b9423e6f12e9be0977332c9d2be9865253ed030685b4ae7d7e4fcb45132e5f0a9dbc84fdd823a8150563e588451028fde205a4275b429
|
7
|
+
data.tar.gz: ad2fda272424b398d077ed2b80bc940dc225283970652010daa691fc3662b31f479d6440a709200646f830c9c951a58067442711cd633b0625534d75075b2174
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@ EnumAccessor lets you define enum for attributes, and store them as integer in t
|
|
4
4
|
|
5
5
|
It is very similar to [Official Rails 4.1 Implementation](http://edgeguides.rubyonrails.org/4_1_release_notes.html#active-record-enums), but EnumAccessor offers quite a few advantages:
|
6
6
|
|
7
|
-
*
|
7
|
+
* No-conflict safe predicate methods (`user.status_active?` instead of `user.active?`)
|
8
8
|
* Validation
|
9
9
|
* Scope
|
10
10
|
* Translation
|
@@ -40,7 +40,7 @@ user.gender = :male
|
|
40
40
|
user.gender_female? # => false
|
41
41
|
user.gender_raw # => 1
|
42
42
|
|
43
|
-
User.genders
|
43
|
+
User.genders # => { 'female' => 0, 'male' => 1 }
|
44
44
|
```
|
45
45
|
|
46
46
|
Notice that zero-based numbering is used as database values.
|
@@ -79,12 +79,18 @@ Also takes multiple values.
|
|
79
79
|
User.where_status(:active, :pending)
|
80
80
|
```
|
81
81
|
|
82
|
+
To use under direct `where` context (e.g. `find_by` or `find_or_create_by`), pass integer value.
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
Social.find_or_create_by(kind: Social.kinds[:facebook], external_id: facebook_user_id)
|
86
|
+
```
|
87
|
+
|
82
88
|
## Validations
|
83
89
|
|
84
|
-
|
90
|
+
By default, models are validated using `inclusion`. To disable, pass `false` to `validates` option.
|
85
91
|
|
86
92
|
```ruby
|
87
|
-
enum_accessor :status, [:on, :off], validates:
|
93
|
+
enum_accessor :status, [:on, :off], validates: false
|
88
94
|
```
|
89
95
|
|
90
96
|
You can also pass validation options.
|
@@ -112,15 +118,17 @@ and now `human_*` methods return a translated string. It defaults to `humanize`
|
|
112
118
|
```ruby
|
113
119
|
I18n.locale = :ja
|
114
120
|
user.human_gender # => '女'
|
115
|
-
User.
|
121
|
+
User.human_genders # => { 'female' => '女', 'male' => '男' }
|
116
122
|
|
117
123
|
I18n.locale = :en
|
118
124
|
user.human_gender # => 'Female'
|
119
|
-
User.
|
125
|
+
User.human_genders # => { 'female' => 'Female', 'male' => 'Male' }
|
120
126
|
```
|
121
127
|
|
122
128
|
## Changelog
|
123
129
|
|
130
|
+
- v2.0.0:
|
131
|
+
- Reworked to remove the "dict" methods. Now `User.genders.dict` is `User.genders` and `User.genders.human_dict` is `User.human_genders`
|
124
132
|
- v1.1.0:
|
125
133
|
- Validate by default again.
|
126
134
|
- Added `:class_attribute` option to specify class attribute to hold definitions
|
data/lib/enum_accessor.rb
CHANGED
@@ -7,20 +7,33 @@ module EnumAccessor
|
|
7
7
|
|
8
8
|
module ClassMethods
|
9
9
|
def enum_accessor(column, keys, options={})
|
10
|
+
# Normalize keys
|
11
|
+
dict = case keys
|
12
|
+
when Array
|
13
|
+
Hash[keys.map.with_index{|i,index| [i, index] }]
|
14
|
+
when Hash
|
15
|
+
keys
|
16
|
+
else
|
17
|
+
raise ArgumentError.new('enum_accessor takes Array or Hash as the second argument')
|
18
|
+
end
|
19
|
+
|
20
|
+
# Define class attributes
|
10
21
|
definition = options[:class_attribute] || column.to_s.pluralize.to_sym
|
11
22
|
class_attribute definition
|
12
|
-
|
23
|
+
class_attribute "_human_#{definition}"
|
24
|
+
send "#{definition}=", dict.with_indifferent_access.freeze
|
25
|
+
send "_human_#{definition}=", {}
|
13
26
|
|
14
27
|
# Getter
|
15
28
|
define_method(column) do
|
16
|
-
send(definition).
|
29
|
+
send(definition).key(read_attribute(column))
|
17
30
|
end
|
18
31
|
|
19
32
|
# Setter
|
20
33
|
define_method("#{column}=") do |arg|
|
21
34
|
case arg
|
22
35
|
when String, Symbol
|
23
|
-
write_attribute column, send(definition)
|
36
|
+
write_attribute column, send(definition)[arg]
|
24
37
|
when Integer, NilClass
|
25
38
|
write_attribute column, arg
|
26
39
|
end
|
@@ -32,7 +45,7 @@ module EnumAccessor
|
|
32
45
|
end
|
33
46
|
|
34
47
|
# Predicate
|
35
|
-
send(definition).
|
48
|
+
send(definition).each do |key, int|
|
36
49
|
define_method("#{column}_#{key}?") do
|
37
50
|
read_attribute(column) == int
|
38
51
|
end
|
@@ -40,10 +53,17 @@ module EnumAccessor
|
|
40
53
|
|
41
54
|
# Human-friendly print
|
42
55
|
define_method("human_#{column}") do
|
43
|
-
send(definition)
|
56
|
+
self.class.send("human_#{definition}")[send(column)]
|
44
57
|
end
|
45
58
|
|
46
59
|
# Human-friendly print on class level
|
60
|
+
define_singleton_method("human_#{definition}") do
|
61
|
+
send("_human_#{definition}")[I18n.locale] ||= begin
|
62
|
+
Hash[send(definition).keys.map{|key| [key, send("human_#{column}", key)] }].with_indifferent_access.freeze
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Internal method for translation
|
47
67
|
# Mimics ActiveModel::Translation.human_attribute_name
|
48
68
|
define_singleton_method "human_#{column}" do |key, options={}|
|
49
69
|
defaults = lookup_ancestors.map do |klass|
|
@@ -60,7 +80,7 @@ module EnumAccessor
|
|
60
80
|
|
61
81
|
# Scopes
|
62
82
|
define_singleton_method "where_#{column}" do |*args|
|
63
|
-
integers = args.map{|arg| send(definition)
|
83
|
+
integers = args.map{|arg| send(definition)[arg] }.compact
|
64
84
|
where(column => integers)
|
65
85
|
end
|
66
86
|
|
@@ -70,33 +90,7 @@ module EnumAccessor
|
|
70
90
|
end
|
71
91
|
unless options[:validates] == false
|
72
92
|
validation_options = options[:validates].is_a?(Hash) ? options[:validates] : {}
|
73
|
-
validates column, { inclusion: { in: send(definition).
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
class Definition
|
78
|
-
attr_accessor :dict
|
79
|
-
|
80
|
-
def initialize(column, keys, klass)
|
81
|
-
dict = case keys
|
82
|
-
when Array
|
83
|
-
Hash[keys.map.with_index{|i,index| [i, index] }]
|
84
|
-
when Hash
|
85
|
-
keys
|
86
|
-
else
|
87
|
-
raise ArgumentError.new('enum_accessor takes Array or Hash as the second argument')
|
88
|
-
end
|
89
|
-
|
90
|
-
@column = column
|
91
|
-
@klass = klass
|
92
|
-
@dict = dict.with_indifferent_access.freeze
|
93
|
-
@human_dict = {}
|
94
|
-
end
|
95
|
-
|
96
|
-
def human_dict
|
97
|
-
@human_dict[I18n.locale] ||= begin
|
98
|
-
Hash[@dict.keys.map{|key| [key, @klass.send("human_#{@column}", key)] }].with_indifferent_access.freeze
|
99
|
-
end
|
93
|
+
validates column, { inclusion: { in: send(definition).keys } }.merge(validation_options)
|
100
94
|
end
|
101
95
|
end
|
102
96
|
end
|
data/spec/enum_accessor_spec.rb
CHANGED
@@ -43,20 +43,20 @@ describe EnumAccessor do
|
|
43
43
|
it 'adds humanized methods' do
|
44
44
|
I18n.locale = :ja
|
45
45
|
expect(User.human_attribute_name(:gender)).to eq('性別')
|
46
|
-
expect(User.
|
47
|
-
expect(User.
|
46
|
+
expect(User.human_genders).to eq({ 'female' => '女', 'male' => '男' })
|
47
|
+
expect(User.human_genders[:female]).to eq('女')
|
48
48
|
expect(@user.human_gender).to eq('女')
|
49
49
|
|
50
50
|
I18n.locale = :en
|
51
51
|
expect(User.human_attribute_name(:gender)).to eq('Gender')
|
52
|
-
expect(User.
|
53
|
-
expect(User.
|
52
|
+
expect(User.human_genders).to eq({ 'female' => 'Female', 'male' => 'Male' })
|
53
|
+
expect(User.human_genders[:female]).to eq('Female')
|
54
54
|
expect(@user.human_gender).to eq('Female')
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'adds class methods' do
|
58
|
-
expect(User.genders
|
59
|
-
expect(User.genders
|
58
|
+
expect(User.genders).to eq({ 'female' => 0, 'male' => 1 })
|
59
|
+
expect(User.genders[:female]).to eq(0)
|
60
60
|
end
|
61
61
|
|
62
62
|
it 'supports manual coding' do
|
@@ -111,7 +111,7 @@ describe EnumAccessor do
|
|
111
111
|
# `find_or_create_by` uses where-based raw value for find,
|
112
112
|
# then passes the raw value to the setter method for create.
|
113
113
|
expect {
|
114
|
-
User.find_or_create_by(gender: User.genders
|
114
|
+
User.find_or_create_by(gender: User.genders[:female])
|
115
115
|
}.to change{ User.count }.by(1)
|
116
116
|
end
|
117
117
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enum_accessor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenn Ejima
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|