enum_kit 0.2.3 → 0.3.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/.rbenv-gemsets +1 -0
- data/README.md +20 -21
- data/enum_kit.gemspec +1 -0
- data/lib/enum_kit.rb +4 -56
- data/lib/enum_kit/active_record_patches/enum.rb +1 -15
- data/lib/enum_kit/active_record_patches/enum/enum_type.rb +2 -5
- data/lib/enum_kit/constants.rb +1 -1
- data/lib/enum_kit/railtie.rb +47 -0
- data/spec/active_record/validations/pg_enum_validator_spec.rb +12 -9
- data/spec/internal/app/models/shirt.rb +1 -1
- data/spec/internal/config/initializers/enum_kit.rb +4 -0
- data/spec/spec_helper.rb +5 -5
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e30bee3ea7d57c8fbaf1ac5ca571ee023eb3beb8721572c27192387007b72146
|
4
|
+
data.tar.gz: 87646c8ab4a8945d937d65724bfa83df77e080b81d9242c67efb4f9bba87f861
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3241b467c772bf71e2b9383babebc3de084578f8a95a7a96ccb84a44a1c00e2576c0b9d635b40f78b2327b7a879079068e6dc5146f8d6c2820880992dd105d6
|
7
|
+
data.tar.gz: c0564d3bb4188e180366645e6527b30058d058012edbfab3d0f915272ec766e764318b7a52f9207691a53851e6d5523fec8fea3d5cc1dc6f3187e5774ed2b217
|
data/.rbenv-gemsets
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
enum_kit
|
data/README.md
CHANGED
@@ -13,13 +13,16 @@ You can install **EnumKit** using the following command:
|
|
13
13
|
Or, by adding the following to your `Gemfile`:
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
gem 'enum_kit', '~> 0.
|
16
|
+
gem 'enum_kit', '~> 0.3'
|
17
17
|
```
|
18
18
|
|
19
19
|
### Usage
|
20
20
|
|
21
|
-
Here
|
22
|
-
|
21
|
+
Here is an example migration file that creates an enum called `:shirt_size` and then adds it to the `:shirts` table
|
22
|
+
using the column name `:size`:
|
23
|
+
|
24
|
+
*Pro Tip:* You can omit the `:enum_type` attribute when the name of the enum you want to use exactly matches the name
|
25
|
+
of the column you're adding.
|
23
26
|
|
24
27
|
```ruby
|
25
28
|
class CreateShirts < ActiveRecord::Migration[6.0]
|
@@ -28,7 +31,7 @@ class CreateShirts < ActiveRecord::Migration[6.0]
|
|
28
31
|
|
29
32
|
create_table :shirts do |t|
|
30
33
|
t.string :name
|
31
|
-
t.enum :size,
|
34
|
+
t.enum :size, enum_type: :shirt_size
|
32
35
|
|
33
36
|
t.timestamps
|
34
37
|
end
|
@@ -36,18 +39,18 @@ class CreateShirts < ActiveRecord::Migration[6.0]
|
|
36
39
|
end
|
37
40
|
```
|
38
41
|
|
39
|
-
You can remove
|
42
|
+
You can also remove an enum from the database, but you'll need to remove any associated columns first:
|
40
43
|
|
41
44
|
```ruby
|
42
45
|
class DropShirts < ActiveRecord::Migration[6.0]
|
43
46
|
def change
|
44
|
-
|
45
|
-
drop_enum
|
47
|
+
remove_column :shirts, :size
|
48
|
+
drop_enum :shirt_size
|
46
49
|
end
|
47
50
|
end
|
48
51
|
```
|
49
52
|
|
50
|
-
Once you've defined an enum
|
53
|
+
Once you've defined an enum, you can use it in the associated model with the `#pg_enum` method:
|
51
54
|
|
52
55
|
```ruby
|
53
56
|
class Shirt < ActiveRecord::Base
|
@@ -55,27 +58,23 @@ class Shirt < ActiveRecord::Base
|
|
55
58
|
end
|
56
59
|
```
|
57
60
|
|
58
|
-
Note that you don't need to define the enum's cases again.
|
59
|
-
|
61
|
+
Note that you don't need to define the enum's cases again. The `#pg_enum` method automatically queries the database
|
62
|
+
once when the model is loaded to determine the supported values.
|
60
63
|
|
61
64
|
---
|
62
65
|
|
63
|
-
When setting
|
64
|
-
|
66
|
+
When setting an enum to a value that is not supported, an exception is raised. This can be inconvenient in some cases
|
67
|
+
such as an API where you can't control what value is submitted.
|
65
68
|
|
66
|
-
|
67
|
-
opting for this feature, you'd ideally specify a validation to capture any unsupported values:
|
69
|
+
You can disable the default 'exception raising' behaviour by adding a custom initializer to your Rails project:
|
68
70
|
|
69
71
|
```ruby
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
validates :size, pg_enum: true
|
74
|
-
end
|
72
|
+
# Prevent enums from raising exceptions when set to unsupported values.
|
73
|
+
Rails.application.config.enum_kit.disable_exceptions = true
|
75
74
|
```
|
76
75
|
|
77
|
-
|
78
|
-
enum.
|
76
|
+
Please note that this will affect *all* enums defined in your Rails app, as the `pg_enum` method simply uses the `enum`
|
77
|
+
method behind the scenes. There isn't currently an option to set this on a per enum basis.
|
79
78
|
|
80
79
|
## Development
|
81
80
|
|
data/enum_kit.gemspec
CHANGED
@@ -31,5 +31,6 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_development_dependency 'rake', '~> 13.0'
|
32
32
|
spec.add_development_dependency 'rspec', '~> 3.8'
|
33
33
|
spec.add_development_dependency 'rspec-rails', '~> 3.8'
|
34
|
+
spec.add_development_dependency 'rubocop', '~> 0.77.0'
|
34
35
|
spec.add_development_dependency 'yard', '~> 0.9.20'
|
35
36
|
end
|
data/lib/enum_kit.rb
CHANGED
@@ -3,60 +3,8 @@
|
|
3
3
|
require 'enum_kit/constants'
|
4
4
|
require 'enum_kit/helpers'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
#
|
11
|
-
def self.load!
|
12
|
-
require 'active_record'
|
13
|
-
require 'active_record/connection_adapters/postgresql_adapter'
|
14
|
-
require 'active_support/lazy_load_hooks'
|
15
|
-
|
16
|
-
ActiveSupport.on_load(:active_record) do
|
17
|
-
EnumKit.load_patches!
|
18
|
-
EnumKit.load_extensions!
|
19
|
-
EnumKit.register_database_type!
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# Load the `ActiveRecord` monkey patches.
|
24
|
-
#
|
25
|
-
def self.load_patches!
|
26
|
-
require 'enum_kit/active_record_patches/connection_adapters/postgresql/column_methods'
|
27
|
-
require 'enum_kit/active_record_patches/connection_adapters/postgresql/oid/enum'
|
28
|
-
require 'enum_kit/active_record_patches/connection_adapters/postgresql/oid/type_map_initializer'
|
29
|
-
require 'enum_kit/active_record_patches/enum'
|
30
|
-
require 'enum_kit/active_record_patches/enum/enum_type'
|
31
|
-
require 'enum_kit/active_record_patches/validations/pg_enum_validator'
|
32
|
-
end
|
33
|
-
|
34
|
-
# Load the `ActiveRecord` extensions.
|
35
|
-
#
|
36
|
-
def self.load_extensions!
|
37
|
-
%w[
|
38
|
-
ConnectionAdapters::PostgreSQL::ColumnDumper
|
39
|
-
ConnectionAdapters::PostgreSQL::SchemaDumper
|
40
|
-
ConnectionAdapters::PostgreSQLAdapter
|
41
|
-
Migration::CommandRecorder
|
42
|
-
SchemaDumper
|
43
|
-
].each do |extension|
|
44
|
-
next unless Object.const_defined?("ActiveRecord::#{extension}")
|
45
|
-
|
46
|
-
require File.join('enum_kit', 'active_record_extensions', EnumKit.underscore(extension))
|
47
|
-
|
48
|
-
target_constant = Object.const_get("ActiveRecord::#{extension}")
|
49
|
-
extension_constant = Object.const_get("EnumKit::ActiveRecordExtensions::#{extension}")
|
50
|
-
|
51
|
-
target_constant.prepend(extension_constant)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# Register `:enum` as a native database type.
|
56
|
-
#
|
57
|
-
def self.register_database_type!
|
58
|
-
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:enum] = { name: 'enum' }
|
59
|
-
end
|
6
|
+
if defined?(Rails::Railtie)
|
7
|
+
require 'enum_kit/railtie'
|
8
|
+
else
|
9
|
+
raise 'Unable to load EnumKit without Rails.'
|
60
10
|
end
|
61
|
-
|
62
|
-
EnumKit.load!
|
@@ -25,25 +25,11 @@ module ActiveRecord
|
|
25
25
|
|
26
26
|
# Define a PostgreSQL enum type.
|
27
27
|
#
|
28
|
-
# By default, setting an enum attribute to an unregistered value results in an exception being raised.
|
29
|
-
# You can disable this feature by setting the option `:exceptions` to `false` when registering the enum:
|
30
|
-
# => pg_enum :size, exceptions: false
|
31
|
-
#
|
32
28
|
# @param column_name [String, Symbol] The name of a column representing an enum.
|
33
|
-
# @param options [Hash] Any additional options.
|
34
29
|
#
|
35
|
-
def pg_enum(column_name
|
30
|
+
def pg_enum(column_name)
|
36
31
|
values = pg_enum_values(column_name).map { |v| [v.to_sym, v.to_s] }
|
37
|
-
|
38
32
|
enum(column_name => Hash[values])
|
39
|
-
|
40
|
-
enum = type_for_attribute(column_name)
|
41
|
-
|
42
|
-
raise 'Expected an ActiveRecord::Enum::EnumType' unless enum.is_a?(ActiveRecord::Enum::EnumType)
|
43
|
-
|
44
|
-
enum.disable_exceptions = options.key?(:exceptions) && !options[:exceptions]
|
45
|
-
|
46
|
-
nil
|
47
33
|
end
|
48
34
|
end
|
49
35
|
end
|
@@ -9,14 +9,11 @@ module ActiveRecord
|
|
9
9
|
# :nodoc:
|
10
10
|
#
|
11
11
|
class EnumType < Type::Value
|
12
|
-
# @return [Boolean] Whether to prevent an exception from being raised when the enum is set to an invalid value.
|
13
|
-
#
|
14
|
-
attr_accessor :disable_exceptions
|
15
|
-
|
16
12
|
# :nodoc:
|
17
13
|
#
|
18
14
|
def assert_valid_value(value)
|
19
|
-
return value if value.blank? || mapping.key?(value) || mapping.value?(value)
|
15
|
+
return value if value.blank? || mapping.key?(value) || mapping.value?(value)
|
16
|
+
return value if Rails.application.config.enum_kit.disable_exceptions
|
20
17
|
|
21
18
|
raise ArgumentError, "'#{value}' is not a valid #{name}"
|
22
19
|
end
|
data/lib/enum_kit/constants.rb
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EnumKit
|
4
|
+
# ...
|
5
|
+
#
|
6
|
+
class Railtie < Rails::Railtie
|
7
|
+
initializer 'enum_kit.set_configs' do |app|
|
8
|
+
app.configure do
|
9
|
+
config.enum_kit = ActiveSupport::OrderedOptions.new
|
10
|
+
config.enum_kit.disable_exceptions = false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
initializer 'enum_kit.active_support.register_active_record_handler', after: 'active_support.set_configs' do
|
15
|
+
ActiveSupport.on_load(:active_record) do
|
16
|
+
# Require the ActiveRecord patches.
|
17
|
+
require 'enum_kit/active_record_patches/connection_adapters/postgresql/column_methods'
|
18
|
+
require 'enum_kit/active_record_patches/connection_adapters/postgresql/oid/enum'
|
19
|
+
require 'enum_kit/active_record_patches/connection_adapters/postgresql/oid/type_map_initializer'
|
20
|
+
require 'enum_kit/active_record_patches/enum'
|
21
|
+
require 'enum_kit/active_record_patches/enum/enum_type'
|
22
|
+
require 'enum_kit/active_record_patches/validations/pg_enum_validator'
|
23
|
+
|
24
|
+
# Require the ActiveRecord extensions.
|
25
|
+
%w[
|
26
|
+
ConnectionAdapters::PostgreSQL::ColumnDumper
|
27
|
+
ConnectionAdapters::PostgreSQL::SchemaDumper
|
28
|
+
ConnectionAdapters::PostgreSQLAdapter
|
29
|
+
Migration::CommandRecorder
|
30
|
+
SchemaDumper
|
31
|
+
].each do |extension|
|
32
|
+
next unless Object.const_defined?("ActiveRecord::#{extension}")
|
33
|
+
|
34
|
+
require File.join('enum_kit', 'active_record_extensions', EnumKit.underscore(extension))
|
35
|
+
|
36
|
+
target_constant = Object.const_get("ActiveRecord::#{extension}")
|
37
|
+
extension_constant = Object.const_get("EnumKit::ActiveRecordExtensions::#{extension}")
|
38
|
+
|
39
|
+
target_constant.prepend(extension_constant)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Register `:enum` as a native database type.
|
43
|
+
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:enum] = { name: 'enum' }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,19 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe ActiveRecord::Validations::PgEnumValidator, :unit do
|
4
|
-
subject { Shirt.create(name: 'Plain Shirt', size: :
|
4
|
+
subject { Shirt.create(name: 'Plain Shirt', size: :medium) }
|
5
5
|
|
6
|
-
it '
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
it 'passes validation when using supported values' do
|
7
|
+
%i[small medium large].each do |size|
|
8
|
+
expect(subject.update(size: size)).to eq(true)
|
9
|
+
expect(subject).to be_valid
|
10
|
+
end
|
10
11
|
end
|
11
12
|
|
12
|
-
it '
|
13
|
-
expect
|
13
|
+
it 'fails validation when using an unsupported value' do
|
14
|
+
expect(subject.update(size: :other)).to eq(false)
|
15
|
+
expect(subject).not_to be_valid
|
14
16
|
end
|
15
17
|
|
16
|
-
it '
|
17
|
-
expect
|
18
|
+
it 'fails validation when using nil' do
|
19
|
+
expect(subject.update(size: nil)).to eq(false)
|
20
|
+
expect(subject).not_to be_valid
|
18
21
|
end
|
19
22
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -12,16 +12,16 @@
|
|
12
12
|
#
|
13
13
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
14
14
|
|
15
|
-
# Bundler
|
16
|
-
require 'bundler'
|
17
|
-
|
18
|
-
Bundler.require :default, :test
|
19
|
-
|
20
15
|
# Combustion
|
21
16
|
require 'combustion'
|
22
17
|
|
23
18
|
Combustion.initialize! :active_record
|
24
19
|
|
20
|
+
# Bundler
|
21
|
+
require 'bundler'
|
22
|
+
|
23
|
+
Bundler.require :default, :test
|
24
|
+
|
25
25
|
# Rails
|
26
26
|
require 'rspec/rails'
|
27
27
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enum_kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nialto Services
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '3.8'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rubocop
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 0.77.0
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.77.0
|
139
153
|
- !ruby/object:Gem::Dependency
|
140
154
|
name: yard
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -158,6 +172,7 @@ extensions: []
|
|
158
172
|
extra_rdoc_files: []
|
159
173
|
files:
|
160
174
|
- ".gitignore"
|
175
|
+
- ".rbenv-gemsets"
|
161
176
|
- ".rspec"
|
162
177
|
- ".rubocop.yml"
|
163
178
|
- ".travis.yml"
|
@@ -184,6 +199,7 @@ files:
|
|
184
199
|
- lib/enum_kit/active_record_patches/validations/pg_enum_validator.rb
|
185
200
|
- lib/enum_kit/constants.rb
|
186
201
|
- lib/enum_kit/helpers.rb
|
202
|
+
- lib/enum_kit/railtie.rb
|
187
203
|
- spec/active_record/base_spec.rb
|
188
204
|
- spec/active_record/connection_adapters/postgresql_adapter_spec.rb
|
189
205
|
- spec/active_record/schema_dumper_spec.rb
|
@@ -193,6 +209,7 @@ files:
|
|
193
209
|
- spec/enum_kit/helpers_spec.rb
|
194
210
|
- spec/internal/app/models/shirt.rb
|
195
211
|
- spec/internal/config/database.yml
|
212
|
+
- spec/internal/config/initializers/enum_kit.rb
|
196
213
|
- spec/internal/db/schema.rb
|
197
214
|
- spec/internal/log/.gitignore
|
198
215
|
- spec/spec_helper.rb
|
@@ -232,6 +249,7 @@ test_files:
|
|
232
249
|
- spec/enum_kit/helpers_spec.rb
|
233
250
|
- spec/internal/app/models/shirt.rb
|
234
251
|
- spec/internal/config/database.yml
|
252
|
+
- spec/internal/config/initializers/enum_kit.rb
|
235
253
|
- spec/internal/db/schema.rb
|
236
254
|
- spec/internal/log/.gitignore
|
237
255
|
- spec/spec_helper.rb
|