solnic / virtus

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

Determine attribute from a CoercionError #254

Closed karlfreeman closed 10 years ago

karlfreeman commented 10 years ago

Is there a way to determine the attribute from a CoercionError?

Looking at the example below, the error messages aren't helpful enough IMO for both someone using Virtus but also as someone who could be blindly passed these error messages along.

I've had a look and it appears that this isn't supported. Just checking there isn't a reason before possibly creating a pull?

class Sandwich
  include Virtus.model(strict: true)
  attribute :bread, Symbol
  attribute :filling, Symbol
end

Sandwich.new
# Virtus::CoercionError: Failed to coerce nil into Symbol

Sandwich.new(filling: :parma_ham)
# Virtus::CoercionError: Failed to coerce nil into Symbol

Sandwich.new(bread: :sourdough)
# Virtus::CoercionError: Failed to coerce nil into Symbol

Sandwich.new(filling: :parma_ham, bread: :sourdough)
#<Sandwich:0x007ff05309ec00 @filling=:parma_ham, @bread=:sourdough>

What would be ideal would be something like this:

Sandwich.new(bread: :sourdough)
# Virtus::CoercionError: Attribute 'filling' failed to be coerced from nil into Symbol

Can you tell I'm hungry? :fork_and_knife:

ntl commented 10 years ago

:thumbsup: to this. I prefer my domain objects to enforce strict coersion, because I usually move invariant checking -- #valid? in activerecord parlance -- to command objects (or just command methods in simple cases). Life with strict: true is pretty difficult right now, because the coersion error message doesn't tell you what attribute on what object was problematic.

I'm considering opening a PR for this, but before I started work on that I wanted to chime in on this issue.

solnic commented 10 years ago

Yeah this should definitely be improved. It should also be a very simple thing to implement, just pass whole attribute to coercion error instead of the primitive.