solnic / virtus

[DISCONTINUED ] Attributes on Steroids for Plain Old Ruby Objects
MIT License
3.77k stars 229 forks source link

Coercion not set up correctly for Boolean #184

Closed nyarly closed 11 years ago

nyarly commented 11 years ago

TrueClass seems to work though.

solnic commented 11 years ago

Can you provide an example showing what exactly doesn't work?

nyarly commented 11 years ago

Paraphrasing code I can't share directly:

class Host
  include Virtus

  class Guest
    include Virtus

    attribute :works, TrueClass, :default => true
    attribute :doesnt, Boolean, :default => false
  end

  attribute :guest, Guest
end

h = Host.new(:guest => {:works => "0", :doesnt => "1"})

h.guest.works #=> false
h.guest.doesnt #=> "1"

Spent about an hour tracing through Virtus 1.0.0.beta0 to find how attribute coercion gets set up. Found that a Boolean attribute gets a Virtus::Attribute::Object & :to_object as it's coercion, and TrueClass gets V::A::Boolean.

My rough understanding is that you're relying on inheritance to guess coercion, but Boolean isn't a base Ruby class. Honestly, I don't know where Boolean was defined in the above - it's a big Rails project.

Anyway, it's certainly an irritating surprise (especially since Boolean attributes are used in the Virtus README examples). At least as much as failure to coerce members added to an array would be.

solnic commented 11 years ago

@nyarly I'm guessing it's Mongoid (we had such issues reported in the past). To workaround that simply provide full path to the constant, so Virtus::Attribute::Boolean.