Menu Close

One-to-One relationships with Rails

This is a lot easier than I thought it would be and it actually took me longer than it should have because I was trying to do it manually.

First you need to define the relationship on the parent and children models:


class Person < ActiveRecord::Base has_one :person_details, :dependent=>true
end

class PersonDetails < ActiveRecord::Base belongs_to :person end

Note that this automatically will provide with a person_details member for person when it gets retrieved.

Now on the controller, here's the CRUD:


def create
@person = Person.new(params[:person])
@person_details = PersonDetails.new(params[:person_details])
@person.person_details = @person_details
if @person.save
# Cool, you're done! It saves the person_details as well.
end
end

def edit
@person = Person.find(params[:id])
@person_details = @person.person_details
end

def update
@person = Person.find(params[:id])
if @person.update_attributes(params[:person]) and
@person.person_details.update_attributes(params[:person_details])
# Cool, you're done!
end
end

def destroy
Person.find(params[:id]).destroy
end

Now your rhtml _form.rhtml must have things like:


text_field 'person_details', column.name
text_field 'person, column.name

And you will get two sets of parameters (as you can see in your controller code), params[:person], and params[:person_details]. Your instance variables to set the current values on the view side would be @person and @person_details.

And I was sitting there writing custom code to find/save.. Ugh!

1 Comment

  1. russell

    On edit if you want to save 2 database calls you can put
    @person = Person.find(params[:id], :include =>:person_details)

Comments are closed.