Creating two records at once


#1

Hi there,

I have a User model and a Profile model. A user has_one profile, and a
profile belongs_to a user. The profile model contains a user_id column
as the foreign key.

The problem comes in when I want a user to register. In the
user_controller I have a method that creates the user. I also want the
profile model to be filled in with the appropriate user_id foreign key
(I don’t care about the other columns being filled in at that time).
Here’s what I have: (it obviously doesn’t work… but am I close?)

def register_user
if request.get?
@user = User.new
@profile = Profile.new
else
# Get the parameters from the form and put them in the user object
@user = User.new(params[:user])
@profile = Profile.new(params[:profile])
# Storing the users IP
@user.registered_from_ip = request.remote_ip

  # Set the user's status to a default of 2
  # Status 1 = Admin
  # Status 2 = Member
  # Status 3 = General User
  @user.status = "2"
  @profile.user_id = @user.id

  if @user.save and @profile.save

    redirect_to_index("Thank you for registering

#{@user.first_name} #{@user.last_name}")
end
end
end

The way it works now, the profiles table looks like this when a record
is saved:

mysql> select * from profiles;
±—±-------±---------±--------±------±--------+
| id | gender | homepage | country | about | user_id |
±—±-------±---------±--------±------±--------+
| 1 | NULL | NULL | NULL | NULL | NULL |
±—±-------±---------±--------±------±--------+
1 row in set (0.00 sec)

Are there any examples of what I want to do in the Rails Wiki?

Thank you,
Dave H.


#2

Is a profile just an instance of storing more information about the
user? Or does a Profile represent a type of User? If it is the latter,
then a Profile could have many Users. But I don’t think thats what you
want.

If it is the former, then you’re already set. Since you have
‘belongs_to’ in the Profile side, and you’ve got the user_id in your
profile table. When that row is created, it drops the user_id in.

It looks like you that you need to refer to it as user.profile -
You’ve created two seperate Items, a User and a Profile. If you
created a new User called Me, then did 'Me.profile.country = “USA”,
and then saved, it would do what you want to do.

  • Nic.

On 1/16/06, Dave H. removed_email_address@domain.invalid wrote:

Here’s what I have: (it obviously doesn’t work… but am I close?)
@user.registered_from_ip = request.remote_ip
redirect_to_index("Thank you for registering
| id | gender | homepage | country | about | user_id |
Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails

  • Nic

#3

Thanks Nic. That makes sense that it will automatically create the row
in the profiles table when the user record is saved. However, I’m
still a little lost on exactly where to place the code.

It’s the syntax that messes me up.

I created the new user object and a new profile object
@user = User.new
@profile = Profile.new

When you said, “It looks like that you need to refer to it as
user.profile”, what exactly is “It”?

Thanks,
Dave H.


#4

Hi Dave,
You’ve almost got it, you’re still thinking a little too low-level!

With your two statements:

@user = User.new
@profile = Profile.new

And adding some stuff:
@user.status=“Fired”
@user.name=“John”
@profile.country=“UK”

Stepping aside from what you want to do in your first example, and
just making RoR access Profile, the syntax is this:

@user.profile = @profile

See? (You’ll still need @user.save to make it go in the DB)

But why create another Profile just for assignment? Just create @user,
and then access the profile part like this:

@user.profile.country = “UK”

Quick note: Doing it backwards doesn’t save, ex: @profile.user = @user

Why? Active Record only saved the objects that is assigned in the
‘has_one’ category, in this instance, Profile.

I didn’t think I really addressed your initial question, but more
about the syntax of accessing associated objects, let me know if this
helps (or confuses)

  • Nic.

On 1/16/06, Dave H. removed_email_address@domain.invalid wrote:

When you said, "It looks like that you need to refer to it as

profile model to be filled in with the appropriate user_id foreign key
@profile = Profile.new(params[:profile])
if @user.save and @profile.save
mysql> select * from profiles;
Dave H.
Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails


Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails

  • Nic

#5

Hi Nic… thank you for breaking this down.

I got it to work! I previously had this:

def register_user
if request.get?
@user = User.new
@profile = Profile.new
else
# Get the parameters from the form and put them in the user object
@user = User.new(params[:user])
… and so on…

Everytime I tried to do:
@user.profile = @profile
if @user.save
redirect_to_index(“Thank you for registering
#{@user.first_name} #{@user.last_name}”)
end

It wouldn’t work because @profile was nil.

I fixed it by doing this:

def register_user
if request.get?
@user = User.new
@profile = Profile.new
else
# Get the parameters from the form and put them in the user object
@user = User.new(params[:user])
@profile = Profile.new # <------ This is the line I was missing!
# Storing the users IP
@user.registered_from_ip = request.remote_ip
@user.status = “2”
@user.profile = @profile
if @user.save
redirect_to_index(“Thank you for registering
#{@user.first_name} #{@user.last_name}”)
end
end
end

Everything makes so much more sense. I feel like I’ve had an
enlightening moment this morning.

Thanks again Nic!
-Dave H.