# Has\_many and after\_create

**URL:** <https://www.ruby-forum.com/t/has-many-and-after-create/71586>\
**Category:** Rails\
**Created:** [October 10, 2006, 2:49am UTC](https://www.ruby-forum.com/t/has-many-and-after-create/71586 "2006-10-10T02:49:18Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cocoa\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a87d85/32.png) [@Cocoa\_G](https://www.ruby-forum.com/u/Cocoa_G)\
**Post date:** [October 10, 2006, 2:49am UTC](https://www.ruby-forum.com/t/has-many-and-after-create/71586/1 "2006-10-10T02:49:18Z")

</div>

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  
email?

## Cheers

def self.up  
create\_table “users”, do |t|  
t.column :first\_name, :string  
t.column :last\_name, :string  
end  
create\_table :emails do |t|  
t.column :email\_address, :string  
t.column :primary, :boolean  
t.column :user\_id, :integer  
end  
end

class User \< ActiveRecord::Base  
has\_many :emails, :dependent =\> :destroy  
end

class Email \< ActiveRecord::Base  
belongs\_to :user  
end

class UserController \< ApplicationController  
observer :user\_observer

def signup  
@user = User.new(params[:user])  
@email = Email.new(params[:email])  
return unless request.post?  
@email.user = @user #doesn’t work since @user hasn’t been saved yet  
@email.save!  
@user.save!  
end

end

class UserObserver \< ActiveRecord::Observer  
def after\_create(user)  
UserNotifier.deliver\_welcome(user)  
end  
end

class UserNotifier \< ActionMailer::Base  
def welcome(user)  
setup\_email(user)  
@subject = ‘Welcome’  
@body[:url] = 'Welcome to our website!"  
end

protected  
def setup\_email(user)  
@recipients = “#{Email.find\_by\_user\_id\_and\_primary(user, true)}”  
@from = “removed\_email\_address@domain.invalid”  
@sent\_on = Time.now  
@body[:user] = user  
end  
end

---

<div class="post-metadata">

**Author:** ![Cocoa\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a87d85/32.png) [@Cocoa\_G](https://www.ruby-forum.com/u/Cocoa_G)\
**Post date:** [October 10, 2006, 6:21am UTC](https://www.ruby-forum.com/t/has-many-and-after-create/71586/2 "2006-10-10T06:21:32Z")

</div>

It looks like the standard way of dealing with this issue is to use  
build method added by has\_many:

class UserController \< ApplicationController  
observer :user\_observer

def signup  
@user = User.new(params[:user])  
@email = @user.emails.build(params[:email])  
return unless request.post?  
@user.save!  
end

end

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.

---

<div class="post-metadata">

**Author:** ![Cocoa\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a87d85/32.png) [@Cocoa\_G](https://www.ruby-forum.com/u/Cocoa_G)\
**Post date:** [October 10, 2006, 8:08pm UTC](https://www.ruby-forum.com/t/has-many-and-after-create/71586/3 "2006-10-10T20:08:32Z")

</div>

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:  
[http://blog.inquirylabs.com/2006/09/23/an-after\_create\_before\_association\_create-callback/](http://blog.inquirylabs.com/2006/09/23/an-after_create_before_association_create-callback/)  
(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(user, true).email\_address)

I still have two basic Rails questions:

1. How can I force an observer to be called _after_ all of the object’s  
associated objects have been created?
2. 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.
