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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d86255884f7966bd0e809b50e930e329c42d4b41
4
- data.tar.gz: 6c54bd945c9ae2d6046b5e4b5b13b27dc8cdc01d
3
+ metadata.gz: 14d9609313d6c0cf506e0ddec8e2e1b040f0f0a4
4
+ data.tar.gz: 55f3e47cc0ad9fc6a638428ffeae93d820c556a6
5
5
  SHA512:
6
- metadata.gz: 6a19a3a40b302f92ac389bde732a5c461d6b5927885eeefce29d5ab0fcede07dc49f98f295ce6504577a23705d4de303303e9a25703d962406791379b1db7be8
7
- data.tar.gz: d02c42efa9212eba91bd9a90fdb6bf36f717786a55953319f4c892bb0201f8d69e765c3f1ef71570fe57b9ea46446f90af178354a7ff26978538be4b1cade89b
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
- * Safe predicate methods (`user.status_active?` instead of `user.active?`)
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.dict # => { 'female' => 0, 'male' => 1 }
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
- You can pass `validates: true` to enable validation.
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: true
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.genders.human_dict # => { 'female' => '女', 'male' => '男' }
121
+ User.human_genders # => { 'female' => '女', 'male' => '男' }
116
122
 
117
123
  I18n.locale = :en
118
124
  user.human_gender # => 'Female'
119
- User.genders.human_dict # => { 'female' => 'Female', 'male' => 'Male' }
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
- send "#{definition}=", Definition.new(column, keys, self)
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).dict.key(read_attribute(column))
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).dict[arg]
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).dict.each do |key, int|
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).human_dict[send(column)]
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).dict[arg] }.compact
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).dict.keys } }.merge(validation_options)
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
@@ -1,3 +1,3 @@
1
1
  module EnumAccessor
2
- VERSION = '1.1.0'
2
+ VERSION = '2.0.0'
3
3
  end
@@ -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.genders.human_dict).to eq({ 'female' => '女', 'male' => '男' })
47
- expect(User.genders.human_dict[:female]).to eq('女')
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.genders.human_dict).to eq({ 'female' => 'Female', 'male' => 'Male' })
53
- expect(User.genders.human_dict[:female]).to eq('Female')
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.dict).to eq({ 'female' => 0, 'male' => 1 })
59
- expect(User.genders.dict[:female]).to eq(0)
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.dict[:female])
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: 1.1.0
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-23 00:00:00.000000000 Z
11
+ date: 2014-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport