Skip to content

Commit

Permalink
Fixes an issue with select_options on nil/blank objects
Browse files Browse the repository at this point in the history
This was a regression from 2.x where the ActiveRecord object was setting
enum options on itself. Because these options were no longer available,
there was no way to determine the associated enum if the value was nil
or blank. This introduces a sort of null object that is just a subclass
of the base enum that behaves like a nil or blank object.
  • Loading branch information
beerlington committed Aug 21, 2012
1 parent db53df6 commit 29e4b89
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 5 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# ClassyEnum Changelog

## 3.1.1

* Fixes a regression with Formtastic support. ClassyEnumm::Base.build now
returns a null object that decends from the base_class when the argument is
blank (nil, empty string, etc). This allows the ActiveRecord model's enum
attribute to respond to enum methods even if it is blank.

## 3.1.0

* ClassyEnum::Base now extends Enumerable to provide enum collection
Expand Down
12 changes: 11 additions & 1 deletion lib/classy_enum/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class Base

class << self
def inherited(klass)
return if klass.anonymous?

if self == ClassyEnum::Base
klass.base_class = klass
else
Expand Down Expand Up @@ -59,7 +61,15 @@ def inherited(klass)
def build(value, options={})
object = find(value)

return value if object.nil? || (options[:allow_blank] && object.nil?)
if object.nil? || (options[:allow_blank] && object.nil?)
return value unless value.blank?

# Subclass the base class and make it behave like the value that it is
object = Class.new(base_class) {
instance_variable_set(:@option, value)
delegate :blank?, :nil?, :to => :option
}.new
end

object.owner = options[:owner]
object.serialize_as_json = options[:serialize_as_json]
Expand Down
11 changes: 8 additions & 3 deletions lib/classy_enum/conversion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,13 @@ def to_i
# class Priority < ClassyEnum::Base
# end
#
# class Priority::Low < Priority; end
# class Priority::Medium < Priority; end
# class Priority::Low < Priority; end # class Priority::Medium < Priority; end
# class Priority::High < Priority; end
#
# @priority = Priority::Low.new
# @priority.to_s # => 'low'
def to_s
self.class.instance_variable_get('@option').to_s
option.to_s
end

# Returns a Symbol corresponding to a string representation of element,
Expand Down Expand Up @@ -65,5 +64,11 @@ def as_json(options=nil)
json
end

private

def option
self.class.instance_variable_get(:@option)
end

end
end
2 changes: 1 addition & 1 deletion lib/classy_enum/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module ClassyEnum
VERSION = "3.1.0"
VERSION = "3.1.1"
end
14 changes: 14 additions & 0 deletions spec/classy_enum/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ class ClassyEnumBase::Two < ClassyEnumBase
subject { ClassyEnumBase.build(:two) }
it { should be_a(ClassyEnumBase::Two) }
end

context 'nil' do
subject { ClassyEnumBase.build(nil) }
it { should be_a(ClassyEnumBase) }
it { should be_nil }
it { should be_blank }
end

context 'empty string' do
subject { ClassyEnumBase.build('') }
it { should be_a(ClassyEnumBase) }
it { should_not be_nil }
it { should be_blank }
end
end

context '#new' do
Expand Down

0 comments on commit 29e4b89

Please sign in to comment.