Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

create with a block and after_initialize have inconsistant behavior #2074

Closed
hmcfletch opened this Issue · 4 comments

3 participants

@hmcfletch

The problem I am running into when I create and object that uses after_initialize to set up default values for attributes that are dependent on other attributes and set some of the values for the new object in a block.

Let's say I have the following class with an after_initialize to set up the msrp based on the given wholesale value.

class Product < ActiveRecord::Base
  after_initialize :set_defaults

  def set_defaults
    self.msrp = 2 * wholesale unless wholesale.nil?
  end
end

If I create a product like so

Product.create(:name => 'Awesome Product', :wholesale => 10)

I'll get the following product object:

<Product id:1234, name: "Awesome Product", wholesale: 10, msrp: 20>

But if I create the object like so

Product.create do |p|
  p.name = 'Awesome Product'
  p.wholesale => 10
end

I''l get the following

<Product id:1234, name: "Awesome Product", wholesale: 10, msrp: nil>

I know why this happens. It happens because create (in ActiveRecord::Base) with a block given calls new first, which triggers after_initialize, then yields to the block with the new object. Since the wholesale value is set in the block, after_initialize doesn't have access to it to set msrp.

Sorry for not providing a patch, I haven't dug around enough to figure out what would be the best way to adress this. Figured it was important enough to at least raise the issue first.

@bhus

What about passing block to initialize method? That seems like a logical choice after a first glance.

@hmcfletch

Not sure why I didn't think of that. I'll have a look at it this weekend and see what happens when you do that.

@bhus

good luck!

@cldwalker cldwalker referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@cldwalker cldwalker referenced this issue from a commit in cldwalker/rails
@hmcfletch hmcfletch fix after_initialize edge case (close #2074 and close #2175)
fix behavior when after_initialize is defined and a block is passed to Base.create
3dc5f71
@cldwalker cldwalker referenced this issue from a commit in cldwalker/rails
@hmcfletch hmcfletch fix after_initialize edge case (close #2074 and close #2175)
fix behavior when after_initialize is defined and a block is passed to Base.create
f956759
@spastorino
Owner

Merged here

@spastorino spastorino closed this
@ttosch ttosch referenced this issue from a commit
@hmcfletch hmcfletch fix after_initialize edge case (close #2074 and close #2175)
fix behavior when after_initialize is defined and a block is passed to Base.create
96fa2fa
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.