Skip to content

Commit

Permalink
Merge tag '0.3.1' into develop
Browse files Browse the repository at this point in the history
Added .id_from_enumbler method
  • Loading branch information
thornomad committed Apr 29, 2020
2 parents eabf2db + c7c63b6 commit ab79dea
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 33 deletions.
20 changes: 4 additions & 16 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ Lint/RaiseException:
Lint/StructNewOverride:
Enabled: true

Style/Documentation:
Enabled: false

Style/HashEachMethods:
Enabled: true

Expand All @@ -38,20 +41,5 @@ Style/TrailingCommaInArrayLiteral:
Enabled: true
EnforcedStyleForMultiline: consistent_comma

Metrics/BlockLength:
Metrics:
Enabled: false

Metrics/AbcSize:
Enabled: false

Metrics/CyclomaticComplexity:
Enabled: false

Metrics/MethodLength:
Max: 30

Metrics/ModuleLength:
Max: 300

Metrics/ClassLength:
Max: 300
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
PATH
remote: .
specs:
enumbler (0.3.0)
activerecord (>= 6.0)
activesupport (>= 6.0)
enumbler (0.3.1)
activerecord (~> 6.0.2)
activesupport (~> 6.0.2)

GEM
remote: https://rubygems.org/
Expand Down
52 changes: 51 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,56 @@
# Enumbler

`Enums` are terrific, but they lack integrity. Enumbler!
`Enums` are terrific, but they lack integrity. Enumbler! The _enum enabler_! The goal is to allow one to maintain a true foreign_key database driven relationship that also behaves a little bit like an `enum`. Best of both worlds? We hope so.


## Example

Suppose you have a `House` and you want to add some `colors` to the house. You are tempted to use an `enum` but the `Enumbler` is calling!

```ruby
ActiveRecord::Schema.define do
create_table :colors|t|
t.string :label, null: false
end

create_table :houses|t|
t.references :color, foreign_key: true, null: false
end
end

class ApplicationRecord < ActiveRecord::Base
include Enumbler
self.abstract_class = true
end

# Our Color has been Enumbled with some basic colors.
class Color < ApplicationRecord
include Enumbler::Enabler

enumble :black, 1
enumble :white, 2
enumble :dark_brown, 3
enumble :infinity, 4, label: 'Infinity - and beyond!'
end

# Our House class, it has a color of course!
class House < ApplicationRecord
enumbled_to :color
end

# This gives you some power:
Color::BLACK # => 1
Color.black # => equivalent to Color.find(1)
Color.black.black? # => true
Color.black.is_black # => true
Color.white.not_black? # => true

house = House.create!(color: Color.black)
house.black?
house.not_black?

House.color(:black) # => [house]
```

## Installation

Expand Down
4 changes: 2 additions & 2 deletions enumbler.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ['lib']

spec.add_dependency 'activerecord', '>= 6.0'
spec.add_dependency 'activesupport', '>= 6.0'
spec.add_dependency 'activerecord', '~> 6.0.2'
spec.add_dependency 'activesupport', '~> 6.0.2'

spec.add_development_dependency 'database_cleaner-active_record', '~> 1.8.0'
spec.add_development_dependency 'fuubar', '~> 2.5'
Expand Down
21 changes: 18 additions & 3 deletions lib/enumbler/enabler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,24 @@ def enumble(enum, id, label: nil, **options)
@enumbles << enumble
end

# Return the record id(s) based on different argument types. Can accept an
# Integer, a Symbol, or an instance of Enumbled model. This lookup is a
# databse-free lookup.
# Return the record id for a given argument. Can accept an Integer, a
# Symbol, or an instance of Enumbled model. This lookup is a database-free
# lookup.
#
# Color.id_from_enumbler(1) # => 1
# Color.id_from_enumbler(:black) # => 1
# Color.id_from_enumbler(Color.black) # => 1
#
# @raise [Error] when there is no enumble to be found
# @param arg [Integer, Symbol, Class]
# @return [Integer]
def id_from_enumbler(arg)
ids_from_enumbler(arg).first
end

# Return the record id(s) based on different argument types. Can accept
# an Integer, a Symbol, or an instance of Enumbled model. This lookup is
# a database-free lookup.
#
# Color.ids_from_enumbler(1, 2) # => [1, 2]
# Color.ids_from_enumbler(:black, :white) # => [1, 2]
Expand Down
2 changes: 1 addition & 1 deletion lib/enumbler/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Enumbler
VERSION = '0.3.0'
VERSION = '0.3.1'
end
34 changes: 27 additions & 7 deletions spec/enumbler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@
end

class ApplicationRecord < ActiveRecord::Base
# @!parse extend Enumbler::ClassMethods
include Enumbler

self.abstract_class = true
end

# Our Color has been Enumbled with some basic colors.
class Color < ApplicationRecord
# @!parse extend Enumbler::ClassMethods
include Enumbler
# @!parse extend Enumbler::Enabler::ClassMethods
include Enumbler::Enabler

enumble :black, 1
enumble :white, 2
Expand All @@ -30,8 +33,6 @@ class Color < ApplicationRecord

# Our House class, it has a color of course!
class House < ApplicationRecord
# @!parse extend Enumbler::ClassMethods
include Enumbler
enumbled_to :color
end

Expand Down Expand Up @@ -69,11 +70,11 @@ class House < ApplicationRecord
it 'creates the query methods', :seed do
expect(Color.black).to be_black
expect(Color.black.is_black).to be true
expect(Color.white).to be_not_black
end
end

describe '.enumbled_to', :seed do
after(:example) { House.enumbled_to(:color) }
it 'raises an error when the class does not exist' do
expect { House.enumbled_to(:bob) }.to raise_error(Enumbler::Error, /cannot be found/)
end
Expand All @@ -92,11 +93,28 @@ class House < ApplicationRecord
it 'raises an error when the Enumble is not defined' do
expect { House.color(100, 1) }.to raise_error(Enumbler::Error, /Unable to find/)
end
it 'allows a prefix to be set' do
it 'allows a scope prefix to be set' do
house = House.create! color: Color.black
House.enumbled_to(:color, prefix: 'where_by')
House.enumbled_to(:color, scope_prefix: 'where_by')
expect(House.where_by_color(:black)).to contain_exactly(house)
end
it 'adds instance methods to query the enumble' do
house = House.new color: Color.black
expect(house).to be_black
expect(house).not_to be_white

expect(house).to be_not_white
expect(house).not_to be_not_black
end
it 'can add a prefix if requested' do
House.enumbled_to(:color, prefix: true)
house = House.new color: Color.black
expect(house).to be_color_black
expect(house).not_to be_color_white

expect(house).to be_color_not_white
expect(house).not_to be_color_not_black
end
end
end

Expand All @@ -112,12 +130,14 @@ class House < ApplicationRecord

describe '.ids_from_enumbler', :seed do
it 'returns a numeric id' do
expect(Color.id_from_enumbler(1)).to eq 1
expect(Color.ids_from_enumbler(1)).to contain_exactly(1)
end
it 'raises an error when the id is not defined' do
expect { Color.ids_from_enumbler(100, 1) }.to raise_error(Enumbler::Error, /Unable to find/)
end
it 'returns an id from a symbol' do
expect(Color.id_from_enumbler(:black)).to eq 1
expect(Color.ids_from_enumbler(:black)).to contain_exactly(1)
expect(Color.ids_from_enumbler(:black, :white)).to contain_exactly(1, 2)
end
Expand Down

0 comments on commit ab79dea

Please sign in to comment.