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 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.
On 2011-10-11, at 11:23 AM, Nikhil G. 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
On Tue, Oct 11, 2011 at 12:23 PM, Nikhil G.
[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:
If you set
class User < ActiveRecord::Base has_many :referrals end
You can do this:
$ rails c Loading development environment (Rails 3.1.1.rc1) 001:0> u = User.new(:name => "Peter") => # 002:0> r1 = u.referrals.build(:comment => "sailor") => # 003:0> r2 = u.referrals.build(:comment => "developer") => # 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 => # 006:0> r1 => # 007:0> r2 => #
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:
validates :comment, :presence => true
And make the validation fail:
$ rails c Loading development environment (Rails 3.1.1.rc1) 001:0> u2 = User.new(:name => "Jan") => # 002:0> r1 = u2.referrals.build(:comment => "wanderer") => # 003:0> r2 = u2.referrals.build ### no comment here ! => # 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
As you can see, nothing got saved, because I tried all saves in one
“atomic”
save.
HTH,
Peter
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:
Best Regards,
Everaldo
On Tue, Oct 11, 2011 at 8:15 AM, Peter V.
On Tue, Oct 11, 2011 at 7:38 PM, Nikhil G.
[email protected]wrote:
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.
@user.build_referral # untested
HTH,
Peter
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
Peter V. 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:
Robert W. wrote in post #1026165:
Peter V. 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:
Sorry, I just realized that is is a has_one rather than has_many, so
please disregard previous reply.
On Oct 11, 10:49pm, Peter V. [email protected]
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@user.build_referral # untested
You were absolutely right, @user.build_referral works, I have tested
it and it has been clearly mentioned in the rubyonrails guides.
@user.referral.build
would have worked only if the association was of the type has_many or
has_and_belongs_to_many
On Tue, Oct 11, 2011 at 11:52 PM, Robert W.
[email protected]wrote:
Sorry, I just realized that is is a has_one rather than has_many, so
please disregard previous reply.
No prob. In reference to
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
On Oct 17, 12:14am, Peter V. [email protected]
wrote:
self.other.build
self.other.create
self.other.create!to make it more uniform ?
HTH,
Peter
Has_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
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs