Creating two records at once

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.

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. [email protected] 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
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails

  • Nic

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.

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. [email protected] 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
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails


Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails

  • Nic

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.