tybro0103
tybro0103

Reputation: 49693

Rails after_create callback can't access model's attributes

I can't access my model's attributes in the after_create callback... seems like I should be able to right?

controller:

@dog = Dog.new(:color => 'brown', :gender => 'male')
@dog.user_id = current_user.id
@dog.save

model:

class Dog < ActiveRecord::Base
  def after_create
    logger.debug "[DOG CREATED] color:#{color} gender:#{gender} user:#{user_id}"
  end
end

console: (all seems well)

>>Dog.last
=>#<Dog id: 1, color: "brown", gender: "male", user_id: 1>

log: (wtf!?)

...
[DOG CREATED] color: gender:male user
...

Some of my attributes show up and others don't! oh no! Anyone know what I'm doing wrong? I've always been able to user after_create in such ways in the past.

Note: The actual variable names and values I used were different, but the methods and code are the same.

Upvotes: 5

Views: 8736

Answers (4)

tybro0103
tybro0103

Reputation: 49693

Figured out my own problem.

One of the attributes was a virtual one, in which I used self.update_attribute...oops!

def price=(amt)
  self.update_attribute(:price_in_cents, (amt*100.0).to_i)
end

So for the record, update_attribute will actually create database record (and trigger after_create) if it hasn't been created yet.

Next time I'll be sure to post full code!

Upvotes: 4

mikewilliamson
mikewilliamson

Reputation: 24783

The macro style callback is probably a better idea generally than simply overriding the method. It lets you fire a few different methods at the same time in the lifecycle (if you want). I think what you need is this:

class Dog < ActiveRecord::Base
  after_create :dog_logger

  def dog_logger
        logger.debug "[DOG CREATED] color:#{self.color} gender:#{self.gender} user:#{self.user_id}"
  end
end

Upvotes: 0

Salil
Salil

Reputation: 47472

Try using after_save instead of after_create may be that works. no tested though.

after_create () Is called after Base.save on new objects that haven‘t been saved yet (no record exists). Note that this callback is still wrapped in the transaction around save. For example, if you invoke an external indexer at this point it won‘t see the changes in the database.

Upvotes: 0

Jimmy Baker
Jimmy Baker

Reputation: 3255

Try this instead:

class Dog < ActiveRecord::Base
  def after_create(dog)
    logger.debug "[DOG CREATED] color:#{dog.color} gender:#{dog.gender} user:#{dog.user_id}"
  end
end

Upvotes: 0

Related Questions