I have a simple model where users have one or more emails and
after_create is used to send new users a Welcome email. If I create
and save a User then after_create is triggered but there is no email
associated with the user. But the problem is that to add an Email to a
User I need to have an id for User which only happens after a save.
So is there a way to create both an Email and a User such that when
the after_create for a user is called, the user has an associated
It looks like the standard way of dealing with this issue is to use
build method added by has_many:
class UserController < ApplicationController
@user = User.new(params[:user])
@email = @user.emails.build(params[:email])
return unless request.post?
This still doesn't solve the problem though, since the observer
registered for after_create is called after the user record is created
but before the email record is created, causing the code to fail since
the email associated with the user hasn't been created yet.
I temporarily resolved this by using an after_create callback rather than an observer and moving the has_many call to after the after_create call as mentioned here:
(I also had to fix a minor bug replacing Email.find_by_user_id_and_primary(user, true) with Email.find_by_user_id_and_primary
I still have two basic Rails questions:
- How can I force an observer to be called after all of the object’s associated objects have been created?
- This technique of placing the callback before or after the has_many association is clever, but is this intended or simply a side effect of the ActiveRecord code? It seems like a fragile technique that can easily break with future Rails releases and I haven’t seen it mentioned elsewhere.