Forum: Ruby on Rails AR clone interaction with initialization logic in model

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
Bb4bdf2b184027bc38d4fb529770cde5?d=identicon&s=25 Wes Gamble (weyus)
on 2007-01-15 20:39

Assume an AR model with an after_initialize method, which is used to
initialize attribute values.  An example would be:

class X < ActiveRecord::Base

  def after_initialize
    self.attr1 = 0

Further assume that x is an instance of X, and x.attr1 has been assigned
the value 3.

If I do y = x.clone, and interrogate the value of y.attr1, I'll get 0.
This makes sense given the source code for AR#clone.  But I expected the
value of attr1 to be 3, not 0.

I would think that clone should completely instantiate the new object,
and _then_ assign the attribute values from the original object.

Is the current behavior a bug, or am I missing some important
philosophical point.

Bb4bdf2b184027bc38d4fb529770cde5?d=identicon&s=25 Wes Gamble (weyus)
on 2007-01-15 21:30
One way around this is to modify the after_initialize logic to not
assume that the attribute values should always be set, like so:

class X < ActiveRecord::Base

  def after_initialize
    if self.new_record?
      self.attr1 ||= 0

In a clone situation, attr1 will already have a value and therefore,
won't be initialized to a default value.

Still, I feel like clone has a bug in it.  Here's what happens in a
regular Ruby object:

class X
  attr_accessor :val

  def initialize
    @val = 5

x =
=> 5
x.val = 23
=> 23
y = x.clone
=> #<X:0x2c33148 @val=23>

The value of @val in the cloned object is 23, not 5.

While I concede that after_initialize is a standalone method that
officially has nothing to do with Ruby object initialization, I still
feel like the clone method should set the attribute values after the
object is instantiated.

This topic is locked and can not be replied to.