You know everything about pretending to be an ActiveRecord::Base
object,
and especially the bit about ActiveRecord::Errors. That part’s really cool.
What we are doing here is making an object that quacks like an
ActiveRecord::Base object but has no database table backing it. As examples: a
search object, a credit card object, or a remote user object. To do this, you
need id, new_record?, and the attributes must work in a specific fashion.
You can also have errors produce an ActiveRecord::Errors instance so user
errors will show in forms and whatnot.
However you may not have noticed that Rails 2.3.4 broke API compatibility for ActiveRecord::Errors. If
your ActiveRecord::Base-like class provides an #errors instance method, it
must now provide these class methods:
self_and_descendants_from_active_record, which produces an array of classes.human_name, which takes an optional hash and produces a string.human_attribute_name, which takes a string and optional hash and produces a string.
The last two of these methods are useful in your day-to-day Rails knowledge (the
first is an internal, undocumented method used by Rails to produce the class
itself and its parents, up to and excluding ActiveRecord::Base).
human_name is used to produce a humanized string representing the class/table
name. If your class is named AuthenticationRecord, .human_name will produce
"Authenticationrecord". Any options you pass to this are normally sent to
I18n.translate.
human_attribute_name is used to map an attribute to a human-readable string.
For example, the attribute created_at is mapped to "Created at". Any options
passed to this are normally sent to I18n.translate.
Here are some tests that need to pass now:
class SearchTest < ActiveSupport::TestCase
should "conform to the ActiveRecord::Errors interface" do
assert_respond_to Search, :self_and_descendants_from_active_record
assert_respond_to Search, :human_name
assert_respond_to Search, :human_attribute_name
assert_equal [Search], Search.self_and_descendants_from_active_record
assert_equal "Search", Search.human_name
assert_equal "Published at", Search.human_attribute_name('published_at')
end
end