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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b664ac9606a62da83707c8dbb8d568692c270492d850d3137d25ccb9690d6cd5
4
- data.tar.gz: 97829f364eb1da0366dd85fb5f3b898a128b62f5af8c460fe53976a96467af68
3
+ metadata.gz: e30bee3ea7d57c8fbaf1ac5ca571ee023eb3beb8721572c27192387007b72146
4
+ data.tar.gz: 87646c8ab4a8945d937d65724bfa83df77e080b81d9242c67efb4f9bba87f861
5
5
  SHA512:
6
- metadata.gz: 2d28e48493d25bf2eb094dce0adf8c37c457959d70b30071e18dca1d9466749852925db512cc96584a8dbe535daaca07c59cbc1685651d2fa8590ca7af747629
7
- data.tar.gz: c64d4bf2f48a506f7ce4056b7de079c3dd423e4a3e8f687b1fc89391e03eb441b477ef0511cc48b697d8ffeb1a4e488ae42e5ad75f557586ac7a4583d8fdb662
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.1'
16
+ gem 'enum_kit', '~> 0.3'
17
17
  ```
18
18
 
19
19
  ### Usage
20
20
 
21
- Here's a sample migration file which creates the enum `:shirt_size`, then adds the column `:size` to the `:shirts`
22
- table using the `:shirt_size` enum as the underlying type:
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, name: :shirt_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 the enum later using something similar to this:
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
- drop_table :shirts
45
- drop_enum :shirt_size
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 in a migration file, you can use it in the associated model:
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
- The `pg_enum` method automatically queries the database when Rails boots for the acceptable values!
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 the enum to an unsupported value, an exception is raised. This can be problematic in cases where you don't
64
- have control over the input (such as when using APIs).
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
- To improve this, you can optionally specify that exceptions should not be raised on a per enum basis. Note that when
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
- class Shirt < ActiveRecord::Base
71
- pg_enum :size, exceptions: false
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
- The above prevents exceptions from being raised and checks that the assigned value is one of the cases supported by the
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
- # Used as a namespace to encapsulate the logic for the EnumKit gem.
7
- #
8
- module EnumKit
9
- # Queue loading of the patches/extensions and database type registration for when `ActiveRecord` has loaded.
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, options = {})
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) || disable_exceptions
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
@@ -3,5 +3,5 @@
3
3
  module EnumKit
4
4
  # @return [String] The gem's semantic version number.
5
5
  #
6
- VERSION = '0.2.3'
6
+ VERSION = '0.3.0'
7
7
  end
@@ -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: :small) }
4
+ subject { Shirt.create(name: 'Plain Shirt', size: :medium) }
5
5
 
6
- it 'permits known values' do
7
- expect { subject.update!(size: :large) }.not_to raise_exception
8
- expect { subject.update!(size: :medium) }.not_to raise_exception
9
- expect { subject.update!(size: :small) }.not_to raise_exception
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 'rejects unknown values' do
13
- expect { subject.update!(size: :other) }.to raise_exception(ActiveRecord::RecordInvalid)
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 'rejects nil values' do
17
- expect { subject.update!(size: nil) }.to raise_exception(ActiveRecord::RecordInvalid)
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
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Shirt < ActiveRecord::Base
4
- pg_enum :size, exceptions: false
4
+ pg_enum :size
5
5
 
6
6
  validates :size, pg_enum: true
7
7
  end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Prevent enums from raising exceptions when set to unsupported values.
4
+ Rails.application.config.enum_kit.disable_exceptions = true
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.2.3
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-05 00:00:00.000000000 Z
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