diff --git a/lib/virtus/attribute/boolean.rb b/lib/virtus/attribute/boolean.rb index c3b72efb..01546a45 100644 --- a/lib/virtus/attribute/boolean.rb +++ b/lib/virtus/attribute/boolean.rb @@ -1,6 +1,21 @@ module Virtus class Attribute + # An "ancestor" for both TrueClass and FalseClass + # Used to correctly build Attribute::Boolean from + # true or false + # + # Needs to be a descendant of TrueClass in order + # to allow Axiom::Type.infer to infer + # Axiom::Types::Boolean from BooleanPrimitive + # + # @private + class BooleanPrimitive < TrueClass + def self.>=(klass) + TrueClass >= klass || FalseClass >= klass + end + end + # Boolean attribute allows true or false values to be set # Additionally it adds boolean reader method, like "admin?" # @@ -15,7 +30,7 @@ class Attribute # post.published? # => false # class Boolean < Attribute - primitive TrueClass + primitive BooleanPrimitive # @api private def self.build_type(*) diff --git a/lib/virtus/support/type_lookup.rb b/lib/virtus/support/type_lookup.rb index a6ce2e39..f90ff411 100644 --- a/lib/virtus/support/type_lookup.rb +++ b/lib/virtus/support/type_lookup.rb @@ -83,7 +83,7 @@ def determine_type_from_primitive(primitive) type = nil descendants.select(&:primitive).reverse_each do |descendant| descendant_primitive = descendant.primitive - next unless primitive <= descendant_primitive + next unless descendant_primitive >= primitive type = descendant if type.nil? or type.primitive > descendant_primitive end type diff --git a/spec/unit/virtus/attribute/class_methods/build_spec.rb b/spec/unit/virtus/attribute/class_methods/build_spec.rb index b9427ed2..f37027b2 100644 --- a/spec/unit/virtus/attribute/class_methods/build_spec.rb +++ b/spec/unit/virtus/attribute/class_methods/build_spec.rb @@ -177,4 +177,18 @@ it { is_expected.to be < Axiom::Types::Collection } end end + + context 'when building from Boolean values' do + context 'when building from true' do + let(:type) { true } + + it { is_expected.to be_instance_of(Virtus::Attribute::Boolean) } + end + + context 'when building from false' do + let(:type) { false } + + it { is_expected.to be_instance_of(Virtus::Attribute::Boolean) } + end + end end