enum_kit 0.2.3 → 0.3.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
  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