views:

551

answers:

4

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.

A: 

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
Jimmy Baker
This is how I'm doing it in my observers.
Jimmy Baker
how do you pass a variable to after_create?
tybro0103
A: 

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.

Salil
A: 

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
Mike Williamson
Yeah, I like this method too, but it wouldn't affect my problem.
tybro0103
A: 

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!

tybro0103