# Two models one form. A lot of headache

**URL:** <https://www.ruby-forum.com/t/two-models-one-form-a-lot-of-headache/119186>\
**Category:** Rails\
**Created:** [November 4, 2007, 5:10pm UTC](https://www.ruby-forum.com/t/two-models-one-form-a-lot-of-headache/119186 "2007-11-04T17:10:19Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thiago\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19b73/32.png) [@Thiago\_G](https://www.ruby-forum.com/u/Thiago_G)\
**Post date:** [November 4, 2007, 5:10pm UTC](https://www.ruby-forum.com/t/two-models-one-form-a-lot-of-headache/119186/1 "2007-11-04T17:10:19Z")

</div>

Hi everyone,

I building a sign up form using two models. One to keep the regular  
user information and the second to keep login and password. I got  
everything working out except for some little details that I can’t  
figure out how to handle.

My models are User and Login. Login has\_one User and User belongs\_to  
Login. Using the User controller I built a action called new which  
display the signup form and save the information in the two different  
databases. The action is working except for the fact that is not  
saving the Login id in the column login\_id at User as was supposed to  
do and for some weird reason is not saving the boolean fields in any  
of the databases.

Below I’m pasting my codes so you can give me some light.

#database structure

class CreateUsers \< ActiveRecord::Migration  
def self.up  
create\_table :users do |t|  
t.column :full\_name, :string  
t.column :street\_address, :text  
t.column :city, :string  
t.column :state, :string  
t.column :country, :string  
t.column :zip\_code, :integer  
t.column :phone, :integer  
t.column :email, :string  
t.column :birth\_date, :date  
t.column :policy\_agreement, :boolean  
t.column :created\_at, :timestamp  
t.column :updated\_at, :timestamp  
end  
end

def self.down  
drop\_table :users  
end  
end

class CreateLogins \< ActiveRecord::Migration  
def self.up  
create\_table :logins do |t|  
t.column :login, :string  
t.column :password, :string  
t.column :ip\_address, :string  
t.column :status, :boolean  
end  
add\_column :users, :login\_id, :integer  
end

def self.down  
drop\_table :logins  
remove\_column :users, :login\_id  
end  
end

#models code

class Login \< ActiveRecord::Base  
has\_one :users  
validates\_uniqueness\_of :login  
validates\_presence\_of :login  
validates\_confirmation\_of :password, :message =\> “should match  
confirmation.”  
end

class User \< ActiveRecord::Base  
belongs\_to :logins

validates\_presence\_of :full\_name  
validates\_presence\_of :street\_address  
validates\_presence\_of :city  
validates\_presence\_of :state  
validates\_presence\_of :country  
validates\_presence\_of :zip\_code  
validates\_numericality\_of :zip\_code, :only\_integer =\> true, :message  
=\> “must contain only numbers.”  
validates\_presence\_of :phone  
validates\_numericality\_of :phone, :only\_integer =\> true, :message =\>  
“must contain only numbers.”  
validates\_presence\_of :email  
validates\_format\_of :email, :with =\> /^([^@\s]+)@((?:[-a-z0-9]+.)+[a-  
z]{2,})$/i  
validates\_uniqueness\_of :email  
validates\_acceptance\_of :policy\_agreement, :message =\> “must be  
accepted. You have to read and agree with the Aykall Policies before  
signing in.”  
validates\_multiparameter\_assignments :message =\> " is not a valid  
date."  
validates\_each :birth\_date do |record, attr, value|  
record.errors.add attr, “is not a valid date. You must be at  
least 18 years old to sign in.” if value \> Date.new((Date.today.year -  
18),(Date.today.month),(Date.today.day))  
end  
end

# controller code

class UserController \< ApplicationController  
layout ‘standard’

def new  
case request.method  
when :post  
@user = User.new(params[:user])  
@login = Login.new(params[:login])  
@user.valid?  
@login.valid?  
if @user.save  
flash[:notice] = ‘Your use account was successfully created.’  
redirect\_to :action =\> ‘search’  
end  
end  
end

end

# view code

# Add a new user

\<%= error\_messages\_for ‘user’, ‘login’ -%\>

\<% form\_for :user, @user, :url =\> { :action =\> “new” } do |user\_form|  
%\>  
  
Full Name: \<%= user\_form.text\_field :full\_name %\>  
  
Street Address: \<%= user\_form.text\_field :street\_address %\>  
  
Country: \<%= user\_form.country\_select :country %\>  
  
State: \<%= user\_form.text\_field :state %\>  
  
City: \<%= user\_form.text\_field :city %\>  
  
Zip Code: \<%= user\_form.text\_field :zip\_code %\>  
  
Phone: \<%= user\_form.text\_field :phone %\>  
  
email: \<%= user\_form.text\_field :email %\>  
  
Policy Agreement: \<%= user\_form.check\_box :policy\_agreement %\>  
  
Birthdate: \<%= user\_form.date\_select :birth\_date, :use\_short\_month  
=\> true, :start\_year =\> 1900, :order =\> [:month, :day, :year] %\>

```
<% fields_for :login, @login do |login_form| %>
  Login: <%= login_form.text_field :login %><br>
  Password: <%= login_form.password_field :password %><br>
  Password Confirmation: <%=

```

login\_form.password\_field :password\_confirmation %\>  
  
\<%= login\_form.hidden\_field :ip\_address, :value =\>  
request.env[‘REMOTE\_IP’] %\>  
\<%= login\_form.hidden\_field :status, :value =\> ‘0’ %\>  
\<% end %\>  
  
  
  
\<%= submit\_tag “Join Now” %\>

\<% end %\>

Let me ask something else. Do you guys think that is safe to store  
passwords in a string field using MySQL? Is there any other way that  
is more secure?

Thanks  
Thiago G.

---

<div class="post-metadata">

**Author:** ![Thiago\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19b73/32.png) [@Thiago\_G](https://www.ruby-forum.com/u/Thiago_G)\
**Post date:** [November 4, 2007, 6:59pm UTC](https://www.ruby-forum.com/t/two-models-one-form-a-lot-of-headache/119186/2 "2007-11-04T18:59:59Z")

</div>

Thiago G. wrote:

> Hi everyone,
> 
> I building a sign up form using two models. One to keep the regular  
> user information and the second to keep login and password. I got  
> everything working out except for some little details that I can’t  
> figure out how to handle.

> Thanks  
> Thiago G.

I think this would get more responses if you had broken your various  
questions up into different posts.

1. The action is working except for the fact that is not saving the  
Login id in the column login\_id at User as was supposed to do.

This sounds like maybe a confusion rather than something not working.  
Me thinks that with the relationship you are using, Login objects know  
about their User, but I don’t understand why you are hoping to get  
“my\_user.login\_id”.

1. for some weird reason is not saving the boolean fields in any of the  
databases.  
Sorry, no clue on this one.

2. Let me ask something else. Do you guys think that is safe to store  
passwords in a string field using MySQL? Is there any other way that  
is more secure?  
No, not safe. You are re-inventing a complex wheel here. Have a look  
at the ActsAsAuthenticated plugin and save yourself a lot of time. It  
will do all of the login stuff for you. Very easy to use.

cheers,  
jp

---

<div class="post-metadata">

**Author:** ![Thiago\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19b73/32.png) [@Thiago\_G](https://www.ruby-forum.com/u/Thiago_G)\
**Post date:** [November 4, 2007, 7:40pm UTC](https://www.ruby-forum.com/t/two-models-one-form-a-lot-of-headache/119186/3 "2007-11-04T19:40:51Z")

</div>

First of all, thanks for your help.

I’m very new to Ruby on Rails. I’m reading the book “Ruby on Rails  
made Easy” and as I do it I’m trying to develop my application.  
So, what you are saying is that with the relation has\_one and  
belongs\_to between my two models there is no need for such a column as  
login\_id in my User database? Rails will automatically know that the  
information placed in row number 132 on my users table belongs to the  
row 136 in my logins table? I’m just asking again because it just  
seems to clever to be true. kkk

Thanks,  
Thiago G.

On Nov 4, 3:59 pm, Jeff P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Thiago\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19b73/32.png) [@Thiago\_G](https://www.ruby-forum.com/u/Thiago_G)\
**Post date:** [November 4, 2007, 8:23pm UTC](https://www.ruby-forum.com/t/two-models-one-form-a-lot-of-headache/119186/4 "2007-11-04T20:23:00Z")

</div>

On 4 Nov 2007, at 16:09, Thiago G. wrote:

> ```
> @user = User.new(params[:user])
> @login = Login.new(params[:login])
> @user.valid?
> @login.valid?
> 
> ```

There’s no way it’s going to magically know that the login created is  
being created for the user in question.  
You probably want @user.build\_login(params[:login)

Fred

---

<div class="post-metadata">

**Author:** ![Thiago\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19b73/32.png) [@Thiago\_G](https://www.ruby-forum.com/u/Thiago_G)\
**Post date:** [November 5, 2007, 9:39am UTC](https://www.ruby-forum.com/t/two-models-one-form-a-lot-of-headache/119186/5 "2007-11-05T09:39:28Z")

</div>

You need the joining columns in the database. Active Record won’t  
create them for you.

In order to express the relationships you need to use build (as last  
post here), otherwise you can explicitly set the ID’s as you want. As  
it is, your relationship is bi directional so you’re going to have to  
create one, create the other using build from the first one (which  
will set the foreign key context for you). Finally you are going to  
need to get the ID of the new record created through build and update  
the parent record so you have the relationship at both ends. This is  
because you can’t know the child’s key until you’ve created it. Once  
this is done it will work fine and login.user and user.login will be  
available to you in your code.

login.create(params[:login])  
user = login.build.user(params[:user])  
login.update\_attribute(:user\_id =\> user.id)

The only question for me is why have a bi-directional relationship? I  
have done this when I’ve used the acts as authenticated plugin so as  
not to pollute the plain user table, but if you are hand-crafting this  
you can do whatever you want. You can create an accessor method in the  
login class

def user

Hope this helps

---

<div class="post-metadata">

**Author:** ![Thiago\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19b73/32.png) [@Thiago\_G](https://www.ruby-forum.com/u/Thiago_G)\
**Post date:** [November 5, 2007, 9:41am UTC](https://www.ruby-forum.com/t/two-models-one-form-a-lot-of-headache/119186/6 "2007-11-05T09:41:48Z")

</div>

… I pressed a control key and it posted on me …

See added in code

On Nov 5, 8:38 am, ghoti [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> because you can’t know the child’s key until you’ve created it. Once  
> you can do whatever you want. You can create an accessor method in the  
> login class

def user  
@user ||= User.find\_by\_login\_id self.id  
end

This will give the effect you want without the bi -directional stuff  
in Active Record
