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
wrote:
On Tue, Oct 11, 2011 at 12:23 PM, Nikhil Goyal 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 rubyonrails-talk@googlegroups.com.
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe@googlegroups.com.
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 rubyonrails-talk@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.

Search Discussions

Discussion Posts

Previous

Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 4 of 11 | next ›
Discussion Overview
grouprubyonrails-talk @
categoriesrubyonrails
postedOct 11, '11 at 10:23a
activeOct 17, '11 at 7:59a
posts11
users5
websiterubyonrails.org
irc#RubyOnRails

People

Translate

site design / logo © 2021 Grokbase