enum_accessor 1.1.0 → 2.0.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: 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