views:

35

answers:

1

This seems to be an inconsistency between has_many and has_one.

The has_many association allows you to specify an after_add callback that is called after an object has been added to the collection.

class Person
  has_many :parents, :after_add => { puts "Added new parent" } # allowed
  has_one :car, :after_add => { puts "Added car" } # not allowed
end

class Car
  after_create :assign_name
  def assign_name
    self.name = "Herbie"
  end
end

Unfortunately, there isn't an after_add callback for the has_one association. How do you achieve the same thing for a has_one?

+1  A: 

I think you can use before_save, and check if the car relation has changed:

before_save :do_something

def do_something
  puts "Added car" if car_changed?
end
Mr. Matt
The original example I gave was a little over-simplified. My real problem includes an after_create callback on the Car model. Unfortunately, Car#after_create is called after Person#before_save so the name isn't available yet.
opsb
You could reverse this, then - in your after_create in your Car model, check if the associated person record is a new_record? and do your processing there.
Mr. Matt
I was hoping to avoid doing that. I've spent long enough trying to find a clean way to do it, doesn't look like there is one at the moment. Maybe it's time to have a crack at the rails source and add the missing callbacks.
opsb
Cool - good luck!
Mr. Matt