Some have argued that there is fundamental flaw in DataMapper: that it "considers booleans to be a superior solution to exceptions." That is, the library does not actively tell you what went wrong when you try to save a record and it fails.
Consider this simple example:
class Person
include DataMapper::Resource
property :id, Serial
property :name, String, :required => true
end
p = Person.new
p.save # => false
Compare this to the behavior you get after requiring dm-noisy-failures
:
require "dm_noisy_failures" # or dm-noisy-failures
p = Person.new
p.save # => DataMapper::SaveFailureError: Person: Name must not be blank
There, isn't that better?
The DataMapper documentation suggests a way to do something similar to the above:
def save_record(record)
if record.save
# The record saved successfully.
else
puts "Errors:"
record.errors.each do |e|
puts e
end
end
end
This works just fine for the simple example above. But what if we change things up a bit?
class Person
has n, :accounts
end
class Account
include DataMapper::Resource
belongs_to :person
property :id, Serial
property :person_id, Integer
property :name, String, :required => true
end
p = Person.new(:name => "John")
p.accounts << Account.new
save_record(p) # => Errors:
What happened? Why don't we see any errors? Because the record passed to save_record
doesn't have any; it's the child record that has the errors.
Now, let's try that again with dm-noisy-failures
required:
require "dm_noisy_failures"
p = Person.new(:name => "John")
p.accounts << Account.new
save_record(p) # => DataMapper::SaveFailureError: Account: Name must not be blank
Awesome! Right?
This gem aliases the default DataMapper methods save
, update
, create
, and destroy
with ?
equivalents (save?
, etc.) which return true or false. The one exception is create?
, which returns either a resource object or nil.
All four methods are then replaced with variations that throw exceptions with informative error messages.
This means that for each operation, there are three options to choose from:
save?
(the old default): return true or falsesave
(the new default): throw exceptions on failuresave!
(already part of DataMapper): save without validating
This library's only dependency is DataMapper itself. Note that you should require dm-noisy-failures
before defining any of your models.