I had setup the associations, one to one, because that was the
requirement

User Model
has_one :referral

Referral Model
belongs_to :user

and I also setup a "user_id" column in Referral model.

But what I did not know was about the magic call "BUILD"

Now I guess, all I have to do is

@user = User.new(:params[:user])
@user.referral.build
@user.save

On Oct 11, 4:15 pm, Peter Vandenabeele <[email protected]> wrote:
> On Tue, Oct 11, 2011 at 12:23 PM, Nikhil Goyal 
> <[email protected]>wrote:
>
> > I have user model and referral model. Referral model has user_id as
> > field.
>
> > Now when a new user is created, I need to call referral#create as well
> > and pass it the id of the newly generated user to user_id of referral
> > model. How can I do that.
>
> I would suggest to not setting the user_id field in the referral object
> manually in your code, but use the built-in mechanisms for:
> * building the objects first in memory
> * saving the object with its associated objects in one "atomic" save.
>
> If you set
>
> <pre>
> class User < ActiveRecord::Base
>   has_many :referrals
> end
> </pre>
>
> You can do this:
>
> <pre>
>  $ rails c
> Loading development environment (Rails 3.1.1.rc1)
> 001:0> u = User.new(:name => "Peter")
> => #<User id: nil, name: "Peter", created_at: nil, updated_at: nil>
> 002:0> r1 = u.referrals.build(:comment => "sailor")
> => #<Referral id: nil, user_id: nil, comment: "sailor", created_at: nil,
> updated_at: nil>
> 003:0> r2 = u.referrals.build(:comment => "developer")
> => #<Referral id: nil, user_id: nil, comment: "developer", created_at: nil,
> updated_at: nil>
> 004:0> u.save
>    (0.4ms)  BEGIN
>   SQL (77.3ms)  INSERT INTO "users" ("created_at", "name", "updated_at")
> VALUES ($1, $2, $3) RETURNING "id"  [["created_at", Tue, 11 Oct 2011
> 10:56:14 UTC +00:00], ["name", "Peter"], ["updated_at", Tue, 11 Oct 2011
> 10:56:14 UTC +00:00]]
>   SQL (1.0ms)  INSERT INTO "referrals" ("comment", "created_at",
> "updated_at", "user_id") VALUES ($1, $2, $3, $4) RETURNING "id"
>  [["comment", "sailor"], ["created_at", Tue, 11 Oct 2011 10:56:14 UTC
> +00:00], ["updated_at", Tue, 11 Oct 2011 10:56:14 UTC +00:00], ["user_id",
> 2]]
>   SQL (0.4ms)  INSERT INTO "referrals" ("comment", "created_at",
> "updated_at", "user_id") VALUES ($1, $2, $3, $4) RETURNING "id"
>  [["comment", "developer"], ["created_at", Tue, 11 Oct 2011 10:56:14 UTC
> +00:00], ["updated_at", Tue, 11 Oct 2011 10:56:14 UTC +00:00], ["user_id",
> 2]]
>    (0.9ms)  COMMIT
> => true
> 005:0> u
> => #<User id: 2, name: "Peter", created_at: "2011-10-11 10:56:14",
> updated_at: "2011-10-11 10:56:14">
> 006:0> r1
> => #<Referral id: 2, user_id: 2, comment: "sailor", created_at: "2011-10-11
> 10:56:14", updated_at: "2011-10-11 10:56:14">
> 007:0> r2
> => #<Referral id: 3, user_id: 2, comment: "developer", created_at:
> "2011-10-11 10:56:14", updated_at: "2011-10-11 10:56:14">
> </pre>
>
> The magic is that you can add multiple referrals to the user in memory
> (without ever writing to
> the database), and when you are fully done with preparing the user and
> the referrals, you do
> one "atomic" save which will write all object to database (or none if it
> fails !).
>
> To demonstrate that, I added to the referrals model a validation:
>
> <pre>
>  validates :comment,  :presence => true
> </pre>
>
> And make the validation fail:
>
> <pre>
> $ rails c
> Loading development environment (Rails 3.1.1.rc1)
> 001:0> u2 = User.new(:name => "Jan")
> => #<User id: nil, name: "Jan", created_at: nil, updated_at: nil>
> 002:0> r1 = u2.referrals.build(:comment => "wanderer")
> => #<Referral id: nil, user_id: nil, comment: "wanderer", created_at: nil,
> updated_at: nil>
> 003:0> r2 = u2.referrals.build ### no comment here !
> => #<Referral id: nil, user_id: nil, comment: nil, created_at: nil,
> updated_at: nil>
> 004:0> u2.save
>    (0.4ms)  BEGIN
>    (0.4ms)  ROLLBACK
> => false
> 005:0> User.find_by_name("Jan")
>   User Load (1.9ms)  SELECT "users".* FROM "users" WHERE "users"."name" =
> 'Jan' LIMIT 1
> => nil
> </pre>
>
> As you can see, nothing got saved, because I tried all saves in one "atomic"
> save.
>
> HTH,
>
> Peter

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en.

Reply via email to