No commit activity in last 3 years
No release in over 3 years
This library replaces the default behavior of DataMapper by raising exceptions with descriptive error messages whenever DB operations are not successfully completed.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

 Project Readme

DataMapper: Noisy Failures

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.

Simple Example

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?

Slightly More Complex Example

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?

Methods Affected

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 false
  • save (the new default): throw exceptions on failure
  • save! (already part of DataMapper): save without validating

Requirements

This library's only dependency is DataMapper itself. Note that you should require dm-noisy-failures before defining any of your models.