New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create with a block and after_initialize have inconsistant behavior #2074

Closed
hmcfletch opened this Issue Jul 14, 2011 · 4 comments

Comments

Projects
None yet
3 participants
@hmcfletch
Copy link
Contributor

hmcfletch commented Jul 14, 2011

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

This comment has been minimized.

Copy link

bhus commented Jul 15, 2011

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

@hmcfletch

This comment has been minimized.

Copy link
Contributor

hmcfletch commented Jul 15, 2011

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

This comment has been minimized.

Copy link

bhus commented Jul 15, 2011

good luck!

cldwalker added a commit to cldwalker/rails that referenced this issue Jul 23, 2011

fix after_initialize edge case (close rails#2074 and close rails#2175)
fix behavior when after_initialize is defined and a block is passed to Base.create

cldwalker added a commit to cldwalker/rails that referenced this issue Jul 24, 2011

fix after_initialize edge case (close rails#2074 and close rails#2175)
fix behavior when after_initialize is defined and a block is passed to Base.create
@spastorino

This comment has been minimized.

Copy link
Member

spastorino commented Jul 25, 2011

Merged here

@spastorino spastorino closed this Jul 25, 2011

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment