Creating/Saving dependent objects

Folks,

Am new to RoR and am building an example to get myself familiar. I am
running into a simple issue while creating a user registration page.

I have a User and Address models defined as below (partial/relevant code
included below). User has_one address and Address belongs_to user. I
have a
foreign key defined in address table that refers to user(id)

In a form I take in username, password, password_confirmation and
address
fields (add_user.rhtml below). I then try to populate the data through
an
add_user action in the user_controller - code included below. For some
reason I am getting a foreign key violation error as below.

*class User < ActiveRecord::Base
has_one :address

validation stuff here

def create_addr(params)
address = Address.new(params[:address])
end*

# Other stuff here
end

class Address < ActiveRecord::Base
belongs_to :user
validates_presence_of :street, :city, :zip
end

class UserController < ApplicationController

  • layout “admin”*

  • def add_user
    if request.post?
    @user = User.new(params[:user])
    @user.last_login_at = Time.now
    @user.create_addr(params)
    begin
    logger.info("---------------> Saving user object
    <-----------------")
    @user.save
    flash[:notice] = “User *#{@user.username #{@user.username*}
    created from new function”
    @user = User.new
    rescue Exception => e
    flash[:notice] = “Can’t save both address and user”
    flash[:notice] = e.message
    end
    end
    end
    end

add_user.rhtml


<%= debug(params) %>
<%= error_messages_for ‘user’ %>
<%= error_messages_for ‘address’ %>
  • Enter User Details*
  • <%= start_form_tag %>

    UserName:
    <%= text_field('user', 'username') %>

    *
  •  <p>
      Password: <br />
      <%= text_field('user', 'password') %>
    </p>*
    
  •  <p>
      Confirm Password: <br />
      <%= text_field('user', 'password_confirmation') %>
    </p>
    
    <p>
      Street: <br />
      <%= text_field('address', 'street') %>
    </p>*
    
  •  <p>
      City: <br />
      <%= text_field('address', 'city') %>
    </p>*
    
  •  <p>
      Zip: <br />
      <%= text_field('address', 'zip') %>
    </p>
    
    <%= submit_tag "Add User", :class => "submit" %>    *
    
  • <%= end_form_tag %>

    <%= button_to "Have Account", :action => :login %>

*

I get the following error message on the page from the Exception (and
log
file)
Mysql::Error: #23000Cannot add or update a child row: a foreign key
constraint fails: INSERT INTO users (hashed_pwd, last_login_at,
salt,
username, firstname, lastname, address_id, company_id,
login_count, created_at)
VALUES(‘fce4d31d2ddf5b0ffd122189b9d575362f79c9c9’, ‘2006-07-07
23:29:09’, ’
302121320.0514656016603112’, ‘rohant’, ‘’, ‘’, 0, 0, 0, ‘2006-06-11
01:39:18’)

The output from debug(params) is as below.

— !ruby/hash:HashWithIndifferentAccess
user: !ruby/hash:HashWithIndifferentAccess
password_confirmation: rohant
username: rohant
password: rohant
commit: Add User
action: add_user
controller: user
address: !ruby/hash:HashWithIndifferentAccess
city: San Jose
zip: “95125”
street: 7777 Pitkin Ct

Clearly I am missing something simple here but am not sure what. The
part I
am not clear about is how does Rails pick up the fact that the address
instance needs to be saved automatically when I save the user instance?
I am
trying to do something similar to what Dave has done with his Depot
example
in his book but obviously something here is not right.

Thanks for any thoughts/pointers you can provide.

Sanjay.

Hi,

You haven’t saved the “address” in your “create_addr” function.

User needs this id. You can check the SQL’s generated in the
development.log
file.

_Hari

View this message in context:
http://www.nabble.com/Creating-Saving-dependent-objects-tf1910146.html#a5229498
Sent from the RubyOnRails Users forum at Nabble.com.

On 7/8/06, Sanjay T. [email protected] wrote:

In a form I take in username, password, password_confirmation and address
address = Address.new(params[:address])
class UserController < ApplicationController
<-----------------")
end
Enter User Details

  <%= submit_tag "Add User", :class => "submit" %>

file)
— !ruby/hash:HashWithIndifferentAccess
street: 7777 Pitkin Ct

Clearly I am missing something simple here but am not sure what. The part I
am not clear about is how does Rails pick up the fact that the address
instance needs to be saved automatically when I save the user instance? I am
trying to do something similar to what Dave has done with his Depot example
in his book but obviously something here is not right.

Truth is that Rails doesn’t know at all most of the time, so your call
to Address.new needs to be followed up by an Address.save unless you
create the address by using the special has_one calls. Rails will
figure it out if you do User.create_address(params[:address]) but if
you create your own address creation function you’ll have to make sure
that you save too.

Check out the has_one/many/habtm functions in the docs, there are a
ton of really awesome prefab functions to do exactly what you’re
working on.

Also, as you would find out after sorting out the saving problem, the
address_id is in the wrong table I believe. foreign_id always lives in
the table that belongs_to the other object. So if address belongs to
user your address row should have user_id rather than the user row
having an address_id. You can change the structure or just switch the
has_one/belongs_to statements. There’s a good snippet about this on
the has_one/many/habtm page of the docs.

http://api.rubyonrails.com/classes/ActiveRecord/Associations/ClassMethods.html

Cheers,
Chuck V.