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. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On 2011-10-11, at 11:23 AM, 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.to answer what you said, in your User model, add the following before_create :generate_referral private def generate_referral self.referrals.create! {referral_attributes} end There are better ways of solving this but I tried to convert your message into code in the most concise way possible> -- > 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Tue, Oct 11, 2011 at 12:23 PM, Nikhil Goyal <goyal.nikhil89-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
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 <peter-jNuWw7i2w7syMbTcgqFhxg@public.gmane.org>wrote:> On Tue, Oct 11, 2011 at 12:23 PM, Nikhil Goyal <goyal.nikhil89-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to > rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
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 <pe...-jNuWw7i2w7syMbTcgqFhxg@public.gmane.org> wrote:> On Tue, Oct 11, 2011 at 12:23 PM, Nikhil Goyal <goyal.nikhi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org 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.
On Tue, Oct 11, 2011 at 7:38 PM, Nikhil Goyal <goyal.nikhil89-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>wrote:> 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 >Hi Nikhil, A few hints. * there is a preference (at least by me) to reply below the previous text as I do here (as opposed to "top quoting") * you can find all details about these association methods in section "4.2 has_one Association Reference" of http://guides.rubyonrails.org/association_basics.html * actually, I believe what you propose above will not work, it would probably be @user.build_referral # untested 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Peter Vandenabeele wrote in post #1026116:> * actually, I believe what you propose above will not work, it would > probably be > > @user.build_referral # untestedActually, your believe isn''t accurate. You should have tested. :) See collection.build and collection.create explained here: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many -- Posted via http://www.ruby-forum.com/. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Robert Walker wrote in post #1026165:> Peter Vandenabeele wrote in post #1026116: >> * actually, I believe what you propose above will not work, it would >> probably be >> >> @user.build_referral # untested > > Actually, your believe isn''t accurate. You should have tested. :) > > See collection.build and collection.create explained here: > >http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many Sorry, I just realized that is is a has_one rather than has_many, so please disregard previous reply. -- Posted via http://www.ruby-forum.com/. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Oct 11, 10:49 pm, Peter Vandenabeele <pe...-jNuWw7i2w7syMbTcgqFhxg@public.gmane.org> wrote:> * you can find all details about these association methods in section > "4.2 has_one Association Reference" ofhttp://guides.rubyonrails.org/association_basics.html > * actually, I believe what you propose above will not work, it would > probably be > > -e4hMzJ1U7sQq8ddH4TG6mw@public.gmane.org_referral # untestedYou were absolutely right, @user.build_referral works, I have tested it and it has been clearly mentioned in the rubyonrails guides.>@user.referral.buildwould have worked only if the association was of the type has_many or has_and_belongs_to_many -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org 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.
On Tue, Oct 11, 2011 at 11:52 PM, Robert Walker <lists-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org>wrote:> Robert Walker wrote in post #1026165: > > Peter Vandenabeele wrote in post #1026116: > >> * actually, I believe what you propose above will not work, it would > >> probably be > >> > >> @user.build_referral # untested > > > > Actually, your believe isn''t accurate. You should have tested. :) > > > > See collection.build and collection.create explained here: > > > > > > http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many > > Sorry, I just realized that is is a has_one rather than has_many, so > please disregard previous reply. >No prob. In reference to http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html I have always been curious why the format of the association methods is so different for the singular compared to collection associations. This then leads to confusion as shown above ... has_many => self.others.xxx (many methods added by has_many) has_one => self.{build|create}_other Maybe for the singular association, we could add self.other.build self.other.create self.other.create! to make it more uniform ? 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Oct 17, 12:14 am, Peter Vandenabeele <pe...-jNuWw7i2w7syMbTcgqFhxg@public.gmane.org> wrote:> I have always been curious why the format of the association methods > is so different for the singular compared to collection associations. This > then > leads to confusion as shown above ... > > has_many => self.others.xxx (many methods added by has_many) > has_one => self.{build|create}_other > > Maybe for the singular association, we could add > > self.other.build > self.other.create > self.other.create! > > to make it more uniform ? > > HTH, > > PeterHas_one is very similar to has_many, in sense, but rails does a LIMIT to 1 when we use has_one. In essence, its a good way to differentiate that we are using has_one or has_many. Thats my understanding and opinion. Regards Nikhil -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org 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.
Possibly Parallel Threads
- Aggregated attribute changed but _was is changed too. So nothing is update in database.
- Rails doesn't validate create_model or build_model (has_one association)
- has value in a console but it's nil in my controller and my view?
- Problems using the authorization plugin from Bill Katz
- Select Tag and Associations