Re: a generic solution to defaults in AR model initialization

John D. Hume
2008-09-08T12:39:13Z

> This afterthought to this ancient but still relevant post
>
http://groups.google.com/group/rubyonrails-core/browse_thread/thread/b509a2fe2b62ac5

I wish you''d also warned how annoying that thread was. It just ruined
my breakfast, and I only got half-way through.

Anyway, I like the functionality. I''d suggest that the instance be
made available to the code providing the defaults. The way you show it
implemented, that would mean making it an argument to #defaults.

  def initialize_with_defaults(attributes=nil,&block)
    defaults = self.class.respond_to?(:defaults) ?
self.class.defaults(self) : false
    ...

But I''m not crazy about that API (or rather, lack thereof), as it
doesn''t communicate intent. I think I''d rather do something
like this.

class Thing < ActiveRecord::Base
  default_attributes do |thing|
    {:name => (thing.type ? "Some #{thing.type}" :
"Unnamed")}
  end
end

or

class Thing < ActiveRecord::Base
  default_attributes :defaults
  def defaults
    {:name => (type ? "Some #{type}" : "Unnamed")}
  end
end

Or we could have something that looked like factory_girl
(http://github.com/thoughtbot/factory_girl/tree/master), though the
feature may not justify the complexity. (Not to mention that if you
wanted the complexity, you could just use factory_girl, though until
now I''d only thought of it as an alternative to fixtures in testing.)

-hume.
---