simple_enum 1.6.9 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/LICENSE +1 -1
- data/README.md +248 -0
- data/Rakefile +4 -21
- data/lib/simple_enum/accessors/accessor.rb +55 -0
- data/lib/simple_enum/accessors/ignore_accessor.rb +11 -0
- data/lib/simple_enum/accessors/whiny_accessor.rb +12 -0
- data/lib/simple_enum/accessors.rb +18 -0
- data/lib/simple_enum/attribute.rb +77 -0
- data/lib/simple_enum/enum.rb +37 -0
- data/lib/simple_enum/hasher.rb +26 -0
- data/lib/simple_enum/mongoid.rb +11 -15
- data/lib/simple_enum/translation.rb +17 -0
- data/lib/simple_enum/version.rb +2 -2
- data/lib/simple_enum.rb +19 -276
- data/simple_enum.gemspec +9 -9
- data/spec/simple_enum/accessors_spec.rb +212 -0
- data/spec/simple_enum/attribute_spec.rb +208 -0
- data/spec/simple_enum/enum_spec.rb +96 -0
- data/spec/simple_enum/hasher_spec.rb +63 -0
- data/spec/simple_enum/mongoid_spec.rb +44 -0
- data/spec/simple_enum/translation_spec.rb +66 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/active_record_support.rb +23 -0
- data/spec/support/i18n_support.rb +12 -0
- data/spec/support/model_support.rb +47 -0
- data/spec/support/mongoid_support.rb +21 -0
- metadata +50 -56
- data/README.rdoc +0 -293
- data/lib/simple_enum/enum_hash.rb +0 -64
- data/lib/simple_enum/validation.rb +0 -58
- data/locales/en.yml +0 -10
- data/test/array_conversions_test.rb +0 -21
- data/test/class_methods_test.rb +0 -114
- data/test/dirty_attributes_test.rb +0 -37
- data/test/enum_hash_test.rb +0 -73
- data/test/finders_test.rb +0 -45
- data/test/locales.yml +0 -25
- data/test/mongoid_test.rb +0 -66
- data/test/object_backed_test.rb +0 -61
- data/test/orm/active_record.rb +0 -114
- data/test/orm/common.rb +0 -23
- data/test/orm/mongoid.rb +0 -114
- data/test/poro_test.rb +0 -20
- data/test/prefixes_test.rb +0 -36
- data/test/simple_enum_test.rb +0 -314
- data/test/test_helper.rb +0 -40
- data/test/without_shortcuts_test.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 665f3d1039443aa384654770a39563ac3d784060
|
4
|
+
data.tar.gz: 44d521782b6390f95dc6b11f3d1c2f6bb570c811
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 200d1e0d6e1367f7f7c66ccd3380452052b3b16547e461d6050d163e1bd7416c4413139284cf4971c1d18439f6ac816a70571fc2b116ab9bbfe52c753bb7fe50
|
7
|
+
data.tar.gz: 0d1238c44c50cd1b2b98d74d68d97a3e9bf4d265b35f9360cd4da59bcaace4eaa2529fa5874a614d3565b5ea5702841499864f6864ea1e1bca424fe7af81625c
|
data/Gemfile
CHANGED
@@ -9,3 +9,6 @@ gem 'mongo', '~> 1.9.0', :platform => :jruby
|
|
9
9
|
gem 'activerecord-jdbcsqlite3-adapter', :platform => :jruby
|
10
10
|
gem 'sqlite3', :platform => :ruby
|
11
11
|
gem 'bson_ext', :platform => :ruby
|
12
|
+
|
13
|
+
# Code coverage on CI only
|
14
|
+
gem "codeclimate-test-reporter", group: :test, require: nil
|
data/LICENSE
CHANGED
data/README.md
ADDED
@@ -0,0 +1,248 @@
|
|
1
|
+
SimpleEnum
|
2
|
+
==========
|
3
|
+
|
4
|
+
[![Build Status](https://travis-ci.org/lwe/simple_enum.svg)](https://travis-ci.org/lwe/simple_enum)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/lwe/simple_enum.png)](https://codeclimate.com/github/lwe/simple_enum)
|
6
|
+
|
7
|
+
Unobtrusive enum-like fields for ActiveRecord and Ruby, brings enums functionality
|
8
|
+
to ActiveRecord and Mongoid models (built for Rails 4+).
|
9
|
+
|
10
|
+
Since version 2.0, simple_enum is no longer compatible with Rails 3.x or Ruby 1.8,
|
11
|
+
use version 1.6 instead: https://github.com/lwe/simple_enum/tree/legacy-1.x
|
12
|
+
|
13
|
+
*Note*: a recent search on github for `enum` turned out, that there are many,
|
14
|
+
many similar solutions. In fact starting with Rails 4.1, there's `ActiveRecord::Enum`
|
15
|
+
which provides **some** of the functionality, but is IMHO pretty limited and too
|
16
|
+
strict in the defaults it provides.
|
17
|
+
|
18
|
+
ActiveRecord Quick start
|
19
|
+
------------------------
|
20
|
+
|
21
|
+
Add this to a model:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
class User < ActiveRecord::Base
|
25
|
+
as_enum :gender, female: 1, male: 0
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
Then create the required `gender_cd` column using migrations:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
class AddGenderColumnToUser < ActiveRecord::Migration
|
33
|
+
def self.up
|
34
|
+
add_column :users, :gender_cd, :integer
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.down
|
38
|
+
remove_column :users, :gender_cd
|
39
|
+
end
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
Mongoid Quick start
|
44
|
+
-------------------
|
45
|
+
|
46
|
+
Due to the dependency on ActiveModel 4.x, the Mongoid integration is only
|
47
|
+
available for mongoid 4.0.0 (which is at beta1 at the moment). If you intend
|
48
|
+
to use simple_enum with another version of mongoid, use version 1.6 instead.
|
49
|
+
|
50
|
+
Load mongoid support in the `Gemfile`:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
gem 'simple_enum', '2.0.0.rc1' , require: 'simple_enum/mongoid'
|
54
|
+
```
|
55
|
+
|
56
|
+
Add this to a model:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
class User
|
60
|
+
include Mongoid::Document
|
61
|
+
include SimpleEnum::Mongoid
|
62
|
+
|
63
|
+
as_enum :gender, female: 1, male: 0
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
The primary difference between AR and mongoid is, that additionaly a field is
|
68
|
+
added to mongoid automatically, the field can be customized by setting `field:`
|
69
|
+
option, or disabled by setting `field: false`.
|
70
|
+
|
71
|
+
Working with enums
|
72
|
+
------------------
|
73
|
+
|
74
|
+
Now it's possible to pull some neat tricks on the new column, yet the original
|
75
|
+
db column (`gender_cd`) is still intact and not touched by anything.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
jane = User.new
|
79
|
+
jane.gender = :female
|
80
|
+
jane.female? # => true
|
81
|
+
jane.male? # => false
|
82
|
+
jane.gender # => :female
|
83
|
+
jane.gender_cd # => 1
|
84
|
+
```
|
85
|
+
|
86
|
+
Easily switch to another value using the bang methods, this does not save
|
87
|
+
the record, only switch the value.
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
joe = User.new
|
91
|
+
joe.male! # => :male
|
92
|
+
joe.gender # => :male
|
93
|
+
joe.gender_cd # => 0
|
94
|
+
```
|
95
|
+
|
96
|
+
Accessing actual enum values is possible at the class level:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
User.genders # => #<SimpleEnum::Enum:0x0....>
|
100
|
+
User.genders[:male] # => 0
|
101
|
+
User.female # => #<ActiveRecord::Relation:0x0.....> (WHERE gender_cd = 1)
|
102
|
+
```
|
103
|
+
|
104
|
+
### Wait, there's more!
|
105
|
+
|
106
|
+
- Too tired of always adding the integer values? Try:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
class User < ActiveRecord::Base
|
110
|
+
as_enum :status, %i{deleted active disabled}
|
111
|
+
# translates to: { deleted: 0, active: 1, disabled: 2 }
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
**Disclaimer**: if you _ever_ decide to reorder this array, beaware that any
|
116
|
+
previous mapping is lost. So it's recommended to create mappings (that might
|
117
|
+
change) using hashes instead of arrays. For stuff like gender it might be
|
118
|
+
probably perfectly fine to use arrays though.
|
119
|
+
- You can store as string values instead of integer values if your database column
|
120
|
+
has the type `string` or `text`:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
class User < ActiveRecord::Base
|
124
|
+
as_enum :status, [:deleted, :active, :disabled], map: :string
|
125
|
+
end
|
126
|
+
|
127
|
+
User.create!(status: :active) #=> #<User id: 1, status_cd: "active">
|
128
|
+
```
|
129
|
+
- Want to use `SimpleEnum` in an ActiveModel, or other class, just add:
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
class MyModel
|
133
|
+
extend SimpleEnum::Attribute
|
134
|
+
attr_accessor :gender_cd
|
135
|
+
as_enum :gender, [:male, :female]
|
136
|
+
end
|
137
|
+
```
|
138
|
+
- Maybe you've columns named differently than the proposed `{column}_cd` naming scheme, feel free to use any column name
|
139
|
+
by providing an option:
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
class User < ActiveRecord::Base
|
143
|
+
as_enum :gender, [:male, :female], source: :sex
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
147
|
+
Starting with 2.0 it's possible to use the same source name as column name.
|
148
|
+
- By default ActiveRecord dirty methods are generated:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
user = User.male.first
|
152
|
+
user.gender = :female
|
153
|
+
user.gender_was
|
154
|
+
# => :male
|
155
|
+
```
|
156
|
+
- Need to provide custom options for the mongoid field, or skip the automatically generated field?
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
# skip field generation
|
160
|
+
field :gender_cd # <- create field manually (!)
|
161
|
+
as_enum :gender, [:male, :female], field: false
|
162
|
+
|
163
|
+
# custom field options (directly passed to Mongoid::Document#field)
|
164
|
+
as_enum :gender, [:male, :female], field: { :type => Integer, :default => 1 }
|
165
|
+
```
|
166
|
+
- To validate enum values simply make use of a `validates :gender, presence: true` validation.
|
167
|
+
If an invalid value is assigned, the gender is set to `nil` by default.
|
168
|
+
- If the shortcut methods (like `female?`, `female!` or `User.male`) conflict with something in your class, it's possible to
|
169
|
+
define a prefix:
|
170
|
+
|
171
|
+
class User < ActiveRecord::Base
|
172
|
+
as_enum :gender, %w{male female}, prefix: true
|
173
|
+
end
|
174
|
+
|
175
|
+
jane = User.new gender: :female
|
176
|
+
jane.gender_female? # => true
|
177
|
+
User.gender_female # => <ActiveRecord::Relation...WHERE gender_cd = 1.>
|
178
|
+
|
179
|
+
The `:prefix` option not only takes a boolean value as an argument, but instead can also be supplied a custom
|
180
|
+
prefix, so with `prefix: 'foo'` all shortcut methods would look like: `foo_<symbol>`
|
181
|
+
- To define which methods are generated it's possible to set `with:` option, by
|
182
|
+
default `with:` is set to `[:attribute, :dirty, :scope]`.
|
183
|
+
|
184
|
+
1. `:attribute` - generates the `male?` and `male!` accessor methods
|
185
|
+
2. `:dirty` - adds the `gender_was` and `gender_changed?` dirty methods
|
186
|
+
3. `:scope` - adds the class level scopes, **if** the `scope` method is present
|
187
|
+
|
188
|
+
- By default the value is set to `nil` when the user sets an invalid value,
|
189
|
+
this behavior can be changed by setting the `accessor:` option. At the moment
|
190
|
+
there are three different behaviors:
|
191
|
+
|
192
|
+
1. `:default` - which sets the value simply to `nil`
|
193
|
+
2. `:whiny` - raises an ArgumentError when trying to set an invalid value
|
194
|
+
3. `:ignore` - keeps the existing value
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
class User < ActiveRecord::Base
|
198
|
+
as_enum :gender, %w{male female}, accessor: :whiny
|
199
|
+
end
|
200
|
+
User.new(gender: "dunno") # => raises ArgumentError
|
201
|
+
```
|
202
|
+
|
203
|
+
See `lib/simple_enum/accessors/*` for more.
|
204
|
+
|
205
|
+
- To define any option globally, e.g. never generating dirty methods, create
|
206
|
+
an initializer and add:
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
# See lib/simple_enum.rb for other options
|
210
|
+
SimpleEnum.with = [:accessor, :scope]
|
211
|
+
```
|
212
|
+
|
213
|
+
## Best practices
|
214
|
+
|
215
|
+
Do not use values named after existing, or well known method names, like `new`, `create` etc.
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
# BAD, conflicts with Rails ActiveRecord Methods (!)
|
219
|
+
as_enum :handle, [:new, :create, :update]
|
220
|
+
|
221
|
+
# GOOD, prefixes all methods
|
222
|
+
as_enum :handle, [:new, :create, :update], :prefix => true
|
223
|
+
```
|
224
|
+
|
225
|
+
Searching for certain values by using the finder methods:
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
User.female # => returns an ActiveRecord::Relation
|
229
|
+
```
|
230
|
+
|
231
|
+
Contributors
|
232
|
+
------------
|
233
|
+
|
234
|
+
* @dmitry - bugfixes and other improvements
|
235
|
+
* @tarsolya - implemented all the ruby 1.9 and rails 3 goodness!
|
236
|
+
* @dbalatero - rails 2.3.5 bugfix & validator fixes
|
237
|
+
* @johnthethird - feature for <tt>_for_select</tt> to return the values
|
238
|
+
* @sinsiliux - ruby 1.9 fixes and removed AR dependency
|
239
|
+
* @sled - mongoid support
|
240
|
+
* @abrom - <tt>find_by_...</tt> method
|
241
|
+
* @mhuggins - translations fixes
|
242
|
+
* @patbenatar - for helping move towards 2.0 (scopes et all)
|
243
|
+
* and all others: https://github.com/lwe/simple_enum/graphs/contributors thanks
|
244
|
+
|
245
|
+
License & Copyright
|
246
|
+
-------------------
|
247
|
+
|
248
|
+
Copyright (c) 2011-2014 by Lukas Westermann, Licensed under MIT Licence (see LICENSE file)
|
data/Rakefile
CHANGED
@@ -5,30 +5,13 @@ require 'rake/testtask'
|
|
5
5
|
Bundler::GemHelper.install_tasks
|
6
6
|
|
7
7
|
desc 'Default: run all unit tests for both ActiveRecord & Mongoid.'
|
8
|
-
task :default => :
|
8
|
+
task :default => :spec
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
t.test_files = Dir['test/*_test.rb']
|
14
|
-
t.verbose = true
|
15
|
-
end
|
16
|
-
|
17
|
-
desc 'Run all unit tests for ActiveRecord'
|
18
|
-
task :activerecord do |t|
|
19
|
-
ENV['SIMPLE_ENUM_TEST_ORM'] = 'active_record'
|
20
|
-
Rake::Task['test:units'].execute
|
21
|
-
end
|
22
|
-
|
23
|
-
desc 'Run all unit tests for Mongoid'
|
24
|
-
task :mongoid do |t|
|
25
|
-
ENV['SIMPLE_ENUM_TEST_ORM'] = 'mongoid'
|
26
|
-
Rake::Task['test:units'].execute
|
27
|
-
end
|
10
|
+
desc 'Run rspec test suite'
|
11
|
+
task :spec do
|
12
|
+
sh 'bundle exec rspec spec/'
|
28
13
|
end
|
29
14
|
|
30
|
-
task :test => [:'test:activerecord', :'test:mongoid']
|
31
|
-
|
32
15
|
# Mongodb
|
33
16
|
directory "tmp/mongodb.data"
|
34
17
|
desc 'Run mongodb in tmp/'
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module SimpleEnum
|
2
|
+
module Accessors
|
3
|
+
class Accessor
|
4
|
+
attr_reader :name, :enum, :source
|
5
|
+
|
6
|
+
def initialize(name, enum, source = nil, prefix = nil)
|
7
|
+
@name = name.to_s
|
8
|
+
@enum = enum
|
9
|
+
@source = source.to_s.presence || "#{name}#{SimpleEnum.suffix}"
|
10
|
+
@prefix = prefix
|
11
|
+
end
|
12
|
+
|
13
|
+
def prefix
|
14
|
+
@cached_prefix ||= @prefix && "#{@prefix == true ? name : @prefix}_" || ""
|
15
|
+
end
|
16
|
+
|
17
|
+
def read(object)
|
18
|
+
enum.key(read_before_type_cast(object))
|
19
|
+
end
|
20
|
+
|
21
|
+
def write(object, key)
|
22
|
+
write_after_type_cast(object, enum[key]) && key
|
23
|
+
end
|
24
|
+
|
25
|
+
def selected?(object, key = nil)
|
26
|
+
current = read_before_type_cast(object)
|
27
|
+
return current && current == enum[key] if key
|
28
|
+
current
|
29
|
+
end
|
30
|
+
|
31
|
+
def changed?(object)
|
32
|
+
object.attribute_changed?(source)
|
33
|
+
end
|
34
|
+
|
35
|
+
def was(object)
|
36
|
+
enum.key(object.attribute_was(source))
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
name
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def read_before_type_cast(object)
|
46
|
+
source == name ? object[source] : object.send(source)
|
47
|
+
end
|
48
|
+
|
49
|
+
def write_after_type_cast(object, value)
|
50
|
+
source == name ? object[source] = value : object.send("#{source}=", value)
|
51
|
+
value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'simple_enum/accessors/accessor'
|
2
|
+
|
3
|
+
module SimpleEnum
|
4
|
+
module Accessors
|
5
|
+
class WhinyAccessor < Accessor
|
6
|
+
def write(object, key)
|
7
|
+
raise ArgumentError, "#{key} is not a valid enum value for #{enum}" if key && !enum.include?(key)
|
8
|
+
super
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'simple_enum/accessors/accessor'
|
2
|
+
require 'simple_enum/accessors/ignore_accessor'
|
3
|
+
require 'simple_enum/accessors/whiny_accessor'
|
4
|
+
|
5
|
+
module SimpleEnum
|
6
|
+
module Accessors
|
7
|
+
ACCESSORS = {
|
8
|
+
ignore: IgnoreAccessor,
|
9
|
+
whiny: WhinyAccessor
|
10
|
+
}
|
11
|
+
|
12
|
+
def self.accessor(name, enum, options = {})
|
13
|
+
access = options.fetch(:accessor, SimpleEnum.accessor)
|
14
|
+
klass = ACCESSORS[access] || Accessor
|
15
|
+
klass.new(name, enum, options[:source], options[:prefix])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'active_support/core_ext/array'
|
2
|
+
|
3
|
+
require 'simple_enum/enum'
|
4
|
+
require 'simple_enum/hasher'
|
5
|
+
require 'simple_enum/accessors'
|
6
|
+
|
7
|
+
module SimpleEnum
|
8
|
+
|
9
|
+
# SimpleEnum::Attribute is the base class to be included in objects to get
|
10
|
+
# the #as_enum functionality. All the including class needs to provide is
|
11
|
+
# a setter and getter for `source`, by default the `source` is `<enum>_cd`.
|
12
|
+
# This is similar to how relations work in Rails, the idea is not taint the
|
13
|
+
# original method.
|
14
|
+
#
|
15
|
+
module Attribute
|
16
|
+
def as_enum(name, values, options = {})
|
17
|
+
options.assert_valid_keys(:source, :prefix, :with, :accessor, :map)
|
18
|
+
|
19
|
+
hash = SimpleEnum::Hasher.map(values, options)
|
20
|
+
enum = SimpleEnum::Enum.new(name, hash)
|
21
|
+
accessor = SimpleEnum::Accessors.accessor(name, enum, options)
|
22
|
+
|
23
|
+
generate_enum_class_accessors_for(enum, accessor)
|
24
|
+
generate_enum_instance_accessors_for(enum, accessor)
|
25
|
+
|
26
|
+
Array.wrap(options.fetch(:with, SimpleEnum.with)).each do |feature|
|
27
|
+
send "generate_enum_#{feature}_methods_for", enum, accessor
|
28
|
+
end
|
29
|
+
|
30
|
+
enum
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def simple_enum_module
|
36
|
+
@simple_enum_module ||= Module.new.tap { |mod| include mod }
|
37
|
+
end
|
38
|
+
|
39
|
+
def generate_enum_class_accessors_for(enum, accessor)
|
40
|
+
name = accessor.name.pluralize
|
41
|
+
singleton_class.send(:define_method, name) { enum }
|
42
|
+
singleton_class.send(:define_method, "#{name}_accessor") { accessor }
|
43
|
+
end
|
44
|
+
|
45
|
+
def generate_enum_instance_accessors_for(enum, accessor)
|
46
|
+
simple_enum_module.module_eval do
|
47
|
+
define_method("#{accessor}") { accessor.read(self) }
|
48
|
+
define_method("#{accessor}=") { |value| accessor.write(self, value) }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def generate_enum_dirty_methods_for(enum, accessor)
|
53
|
+
simple_enum_module.module_eval do
|
54
|
+
define_method("#{accessor}_changed?") { accessor.changed?(self) }
|
55
|
+
define_method("#{accessor}_was") { accessor.was(self) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def generate_enum_attribute_methods_for(enum, accessor)
|
60
|
+
simple_enum_module.module_eval do
|
61
|
+
define_method("#{accessor}?") { |value = nil| accessor.selected?(self, value) }
|
62
|
+
enum.each_pair do |key, value|
|
63
|
+
define_method("#{accessor.prefix}#{key}?") { accessor.selected?(self, key) }
|
64
|
+
define_method("#{accessor.prefix}#{key}!") { accessor.write(self, key) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def generate_enum_scope_methods_for(enum, accessor)
|
70
|
+
return unless respond_to?(:scope)
|
71
|
+
|
72
|
+
enum.each_pair do |key, value|
|
73
|
+
scope "#{accessor.prefix}#{key}", -> { where(accessor.source => value) }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'active_support/core_ext/string'
|
2
|
+
|
3
|
+
module SimpleEnum
|
4
|
+
class Enum
|
5
|
+
attr_reader :name, :hash
|
6
|
+
|
7
|
+
def initialize(name, hash)
|
8
|
+
@name = name.to_s
|
9
|
+
@hash = hash
|
10
|
+
end
|
11
|
+
|
12
|
+
def include?(key)
|
13
|
+
hash.key?(key.to_s) || hash.value?(key)
|
14
|
+
end
|
15
|
+
|
16
|
+
def key(value)
|
17
|
+
key = hash.key(value)
|
18
|
+
key.to_sym if key
|
19
|
+
end
|
20
|
+
|
21
|
+
def value(key)
|
22
|
+
value = hash[key.to_s]
|
23
|
+
value = key if hash.value?(key)
|
24
|
+
value
|
25
|
+
end
|
26
|
+
alias_method :[], :value
|
27
|
+
|
28
|
+
def each_pair(&block)
|
29
|
+
hash.each_pair(&block)
|
30
|
+
end
|
31
|
+
alias_method :each, :each_pair
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
name
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SimpleEnum
|
2
|
+
module Hasher
|
3
|
+
DefaultHasher = ->(values) {
|
4
|
+
Hash.new.tap do |enum_hash|
|
5
|
+
pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
|
6
|
+
pairs.each { |name, value| enum_hash[name.to_s] = value }
|
7
|
+
end
|
8
|
+
}
|
9
|
+
|
10
|
+
StringHasher = ->(values) {
|
11
|
+
Hash.new.tap do |enum_hash|
|
12
|
+
values.each { |name, *args| enum_hash[name.to_s] = name.to_s }
|
13
|
+
end
|
14
|
+
}
|
15
|
+
|
16
|
+
HASHERS = {
|
17
|
+
string: StringHasher
|
18
|
+
}
|
19
|
+
|
20
|
+
def self.map(values, options = {})
|
21
|
+
mapper = options.fetch(:map, SimpleEnum.builder)
|
22
|
+
mapper = HASHERS[mapper] || DefaultHasher unless mapper.respond_to?(:call)
|
23
|
+
mapper.call(values).freeze
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/simple_enum/mongoid.rb
CHANGED
@@ -23,29 +23,25 @@ module SimpleEnum
|
|
23
23
|
# as_enum :gender, [:female, :male], :field => { :type => Integer }
|
24
24
|
#
|
25
25
|
module Mongoid
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
class_attribute :simple_enum_definitions, :instance_writer => false, :instance_reader => false
|
26
|
+
def self.included(base)
|
27
|
+
base.extend SimpleEnum::Attribute
|
28
|
+
base.extend SimpleEnum::Translation
|
29
|
+
base.extend SimpleEnum::Mongoid::ClassMethods
|
31
30
|
end
|
32
31
|
|
33
32
|
module ClassMethods
|
34
|
-
include SimpleEnum::ClassMethods
|
35
|
-
|
36
33
|
# Wrap method chain to create mongoid field and additional
|
37
34
|
# column options
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
# forward custom field options
|
35
|
+
def as_enum(name, values, options = {})
|
36
|
+
source = options[:source].to_s.presence || "#{name}#{SimpleEnum.suffix}"
|
42
37
|
field_options = options.delete(:field)
|
43
|
-
|
38
|
+
unless field_options === false
|
39
|
+
field_options ||= SimpleEnum.field
|
40
|
+
field(source, field_options) if field_options
|
41
|
+
end
|
44
42
|
|
45
|
-
|
46
|
-
as_enum_without_mongoid(enum_cd, values, options)
|
43
|
+
super
|
47
44
|
end
|
48
|
-
alias_method_chain :as_enum, :mongoid
|
49
45
|
end
|
50
46
|
end
|
51
47
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module SimpleEnum
|
2
|
+
module Translation
|
3
|
+
def human_enum_name(enum, key, options = {})
|
4
|
+
defaults = lookup_ancestors.map do |klass|
|
5
|
+
:"#{self.i18n_scope}.enums.#{klass.model_name.i18n_key}.#{enum}.#{key}"
|
6
|
+
end
|
7
|
+
|
8
|
+
defaults << :"enums.#{self.model_name.i18n_key}.#{enum}.#{key}"
|
9
|
+
defaults << :"enums.#{enum}.#{key}"
|
10
|
+
defaults << options.delete(:default) if options[:default]
|
11
|
+
defaults << key.to_s.humanize
|
12
|
+
|
13
|
+
options.reverse_merge! :count => 1, :default => defaults
|
14
|
+
I18n.translate(defaults.shift, options)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/simple_enum/version.rb
CHANGED