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.

Reply via email to