Hi! Last month I was reading "Rails Antipatterns" and if I understood well, your situation fits with one described in the book:
The author says, in page 150: "A presenter is simply a plain old Ruby class that orchestrates the creation of multiple models." I suggest you look for Active Presenter: http://jamesgolick.com/2008/7/27/introducing-activepresenter-the-presenter-library-you-already-know.html https://github.com/jamesgolick/active_presenter Best Regards, Everaldo On Tue, Oct 11, 2011 at 8:15 AM, 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. > -- 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.

