Message from discussion
after_initialize/after_find misfeature
Received: by 10.35.58.8 with SMTP id l8mr2015165pyk.1185130204748;
Sun, 22 Jul 2007 11:50:04 -0700 (PDT)
Return-Path: <pdcaw...@gmail.com>
Received: from py-out-1112.google.com (py-out-1112.google.com [64.233.166.180])
by mx.google.com with ESMTP id k36si2477833waf.2007.07.22.11.50.03;
Sun, 22 Jul 2007 11:50:04 -0700 (PDT)
Received-SPF: pass (google.com: domain of pdcaw...@gmail.com designates 64.233.166.180 as permitted sender)
DomainKey-Status: good (test mode)
Received: by py-out-1112.google.com with SMTP id a25so2878762pyi
for <rubyonrails-core@googlegroups.com>; Sun, 22 Jul 2007 11:50:03 -0700 (PDT)
DKIM-Signature: a=rsa-sha1; c=relaxed/relaxed;
d=gmail.com; s=beta;
h=domainkey-signature:received:received:message-id:date:from:sender:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references:x-google-sender-auth;
b=c+9bBXnj1xj+k9PGZ1xYWzgezWO+RRy0C9MDjMHy27T7k+n02zvHUAbsmIo9XUuHU8yGJlkTKDdrISVhPJ7eqOOHvF1lJxt54o72CZXwOL7bs+ZsZEV9qL2QPKMiGM2xnLm+GqF2jex4PJPFE3JGMqG8MHBqjvDqN8cP48q4iBU=
DomainKey-Signature: a=rsa-sha1; c=nofws;
d=gmail.com; s=beta;
h=received:message-id:date:from:sender:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references:x-google-sender-auth;
b=LXizXm52MXZ1/Pm6IAuoZlSV48IJEeU5ALM2KcIe4SNtZUzhJnyZUXmat1fT17SFQUpeCF+H/x+nRRYUz+M8v9EbIg3KYSb8tk5G8m3PE/euYncNHYsivVmb+DApaXrsP6eBrPaLNK0blw1G9/b8BOf8xpu5SLACS7ueQ4EOo5I=
Received: by 10.35.10.13 with SMTP id n13mr4611037pyi.1185130203463;
Sun, 22 Jul 2007 11:50:03 -0700 (PDT)
Received: by 10.35.16.16 with HTTP; Sun, 22 Jul 2007 11:50:03 -0700 (PDT)
Message-ID: <897e96cc0707221150k776ae7fbgdc6997670c04b9af@mail.gmail.com>
Date: Sun, 22 Jul 2007 19:50:03 +0100
From: "Piers Cawley" <pdcaw...@bofh.org.uk>
Sender: pdcaw...@gmail.com
To: rubyonrails-core@googlegroups.com
Subject: Re: [Rails-core] Re: after_initialize/after_find misfeature
In-Reply-To: <ef46c93e0707221102q4d34cab8hf0e825aa0a651cb4@mail.gmail.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
References: <897e96cc0707220254l750943a2naeab8aaf02499...@mail.gmail.com>
<ef46c93e0707221102q4d34cab8hf0e825aa0a651...@mail.gmail.com>
On 22/07/07, Michael Koziarski <mich...@koziarski.com> wrote:
>
> > More importantly though, it's a huge performance hit for any
> > programmer who wants to do something like setting defaults on their
> > object before it gets written to the database, or even checked for
> > validity.
>
> We have before_validation for this case.
No, you don't.
class Foo < ActiveRecord::Base
def before_validate
self.attrib_with_default ||= 99
end
end
p Foo.new.attrib_with_default # nil
The default doesn't get set until the object is about to be validated,
but sometimes you need that default to be set correctly so that you
can use an object before it's either validated or saved. And are you
really suggesting that everyone should call 'valid?' on their objects
if they want them to get their correct defaults set? Default setting
belongs in the initialization phase, not in the validation phase.
> > If the cost of changing the API in this way is deemed too high, please
> > at least consider adding some callback that really is only called
> > after initialization and not after instantiation. It's too useful a
> > place to ignore.
>
> Taking the case of
>
> 1: @customer = Customer.new(params[:customer])
> 2: @customer.do_something
> 3: @customer.save!
>
> What we currently don't have is a hook that will fire before line 2,
> but not when retrieving from a database. Providing defaults before
> validation was a common case, and I believe that's where the
> before_validation hook came from. What other use cases do you have
> in mind?
Well, the obvious case is the case where you're implementing new in
your controller.
The typical boiler plate goes:
def new
@customer = Customer.new
end
That @customer is never going to be validated, but it does make sense
for it to have its defaults (which belong in the model and not the
controller or the view) set correctly so that 'new.rhtml' doesn't need
any knowledge of any default values when rendering the form.
> The name after_initialize is probably a little misleading because it
> fires even when an object is retrieved from the database. Strictly
> speaking this is 'initialization', but from a user's perspective it's
> 'finding' or 'retrieval'. Perhaps at the very least we could give it
> a less confusing, more hazardous sounding name.
But 'after_initialize' implies "call this after you call the
instance's initialize method", and it's apparent that, in the case of
object retrieval, the initialize method simply isn't called (which
makes sense, because the object is only initialized once, when it got
created by calling its class's new method.)