Skip to content

Commit

Permalink
Merge branch 'release/0.4.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
thornomad committed May 21, 2020
2 parents c7c63b6 + faac99b commit 85f6501
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
enumbler (0.3.1)
enumbler (0.4.0)
activerecord (~> 6.0.2)
activesupport (~> 6.0.2)

Expand Down
48 changes: 33 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,30 @@

`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.

## Installation

## Example
Add this line to your application's Gemfile:

```ruby
gem 'enumbler'
```

And then execute:

$ bundle install

Or install it yourself as:

$ gem install enumbler

## Usage

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
t.string :label, null: false, index: { unique: true }
end

create_table :houses|t|
Expand Down Expand Up @@ -52,25 +67,28 @@ house.not_black?
House.color(:black) # => [house]
```

## Installation
### Use a column other than `label`

Add this line to your application's Gemfile:
By default, the Enumbler expects a table in the database with a column `label`. However, you can change this to another underlying column name. Note that the enumbler still treats it as a `label` column; however it will be saved to the correct place in the database.

```ruby
gem 'enumbler'
```

And then execute:

$ bundle install

Or install it yourself as:
ActiveRecord::Schema.define do
create_table :feelings, force: true do |t|
t.string :emotion, null: false, index: { unique: true }
end
end

$ gem install enumbler
class Feeling < ApplicationRecord
# @!parse extend Enumbler::Enabler::ClassMethods
include Enumbler::Enabler

## Usage
enumbler_label_column_name :emotion

TODO: Write usage instructions here
enumble :sad, 1
enumble :happy, 2
enumble :verklempt, 3, label: 'overcome with emotion'
end
```

## Development

Expand Down
29 changes: 27 additions & 2 deletions lib/enumbler/enabler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ module ClassMethods
#
# # in your migration
# create_table :colors, force: true do |t|
# t.string :label, null: false
# t.string :label, null: false, index: { unique: true }
# end
#
# class Color < ApplicationRecord
Expand All @@ -60,8 +60,9 @@ module ClassMethods
def enumble(enum, id, label: nil, **options)
@enumbles ||= []
@enumbled_model = self
@enumbler_label_column_name ||= :label

enumble = Enumble.new(enum, id, label: label, **options)
enumble = Enumble.new(enum, id, label: label, label_column_name: @enumbler_label_column_name, **options)

if @enumbles.include?(enumble)
raise Error, "You cannot add the same Enumble twice! Attempted to add: #{enum}, #{id}."
Expand All @@ -72,6 +73,30 @@ def enumble(enum, id, label: nil, **options)
@enumbles << enumble
end

# By default, the Enumbler is expecting a table with an underlying column
# named `label` that represents the enum in the database. You can change
# this by calling `enumber_label_column_name` before you `enumble`!
#
# ActiveRecord::Schema.define do
# create_table :feelings, force: true do |t|
# t.string :emotion, null: false, index: { unique: true }
# end
# end
#
# class Feeling < ApplicationRecord
# # @!parse extend Enumbler::Enabler::ClassMethods
# include Enumbler::Enabler
#
# enumbler_label_column_name :emotion
#
# enumble :sad, 1
# enumble :happy, 2
# enumble :verklempt, 3, label: 'overcome with emotion'
# end
def enumbler_label_column_name(label_column_name)
@enumbler_label_column_name = label_column_name
end

# 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.
Expand Down
7 changes: 4 additions & 3 deletions lib/enumbler/enumble.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
module Enumbler
# Class that holds each row of Enumble data.
class Enumble
attr_reader :id, :enum, :label, :options
attr_reader :id, :enum, :label, :label_column_name, :options

def initialize(enum, id, label: nil, **options)
def initialize(enum, id, label: nil, label_column_name: :label, **options)
@id = id
@enum = enum
@label = label || enum.to_s.dasherize
@label_column_name = label_column_name
@options = options
end

Expand All @@ -20,7 +21,7 @@ def ==(other)
def attributes
{
id: id,
label: label,
label_column_name => label,
}
end

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.1'
VERSION = '0.4.0'
end
26 changes: 25 additions & 1 deletion spec/enumbler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
# -----------------------------------------------------------------------------
ActiveRecord::Schema.define do
create_table :colors, force: true do |t|
t.string :label, null: false
t.string :label, null: false, index: { unique: true }
end

create_table :feelings, force: true do |t|
t.string :emotion, null: false, index: { unique: true }
end

create_table :houses, force: true do |t|
Expand All @@ -31,6 +35,17 @@ class Color < ApplicationRecord
enumble :infinity, 4, label: 'This is a made-up color'
end

class Feeling < ApplicationRecord
# @!parse extend Enumbler::Enabler::ClassMethods
include Enumbler::Enabler

enumbler_label_column_name :emotion

enumble :sad, 1
enumble :happy, 2
enumble :verklempt, 3, label: 'overcome with emotion'
end

# Our House class, it has a color of course!
class House < ApplicationRecord
enumbled_to :color
Expand Down Expand Up @@ -118,6 +133,15 @@ class House < ApplicationRecord
end
end

describe '.enumbler_label_column_name' do
before { Feeling.seed_the_enumbler! }
it 'adds the label to the correct column' do
expect(Feeling.verklempt.emotion).to eq 'overcome with emotion'
expect(Feeling.sad).to be_sad
expect(Feeling.enumbles.first).to have_attributes(label: 'sad')
end
end

describe '.enumbles', :seed do
it 'contains the enumbles' do
expect(Color.enumbles.map(&:id)).to contain_exactly(1, 2, 3, 4)
Expand Down

0 comments on commit 85f6501

Please sign in to comment.