1 Form > 2 Models > 2nd Model Requres 1st Model ID

Hey Everyone,

So I have one form that submits information to create 2 models (A, B).
I need the ID of model A to be inserted into model B. But the ID isn’t
created until it hits the database (auto_increment). But if for some
reason either item cannot be created or saved I want to abort the
whole operation.

Whats the best method to do this ?


google “rails 1 form 2 models”

I can handle building two models from 1 form. It’s getting the id from
the first saved model and inserting it in the second and rolling back
the whole transaction if anything goes wrong that is the problem.

Hi brianp
From what I understood you have to put the whole thing in a
transaction like

ActiveRecord::Base.transaction do
save first model object
save second model object


Thanks everyone for your suggestions.

This is what I came up with I was looking for some feedback. It works
fine but I figure I might be doing something long winded. This is my
first go at an actual railsApp other then book demos. Any feedback
would be nice!

// new.html.erb

New word

<%= error_messages_for :word, :definition %>

<% form_for(@word) do |f| %>

<%= f.label :word %>
<%= f.text_field :word %>

<%= f.label :was_created_by %>
<%= f.check_box :was_created_by %>

<% fields_for(:definition, @definition) do |i| %>

<%= i.label :definition %>

<%= i.text_area :definition %>

<%= i.label :word_type %>

<%= i.text_field :word_type %>

<%= i.label :pronounciation %>

<%= i.text_field :pronounciation %>

<%= i.label :origin %>

<%= i.text_area :origin %>

<%= i.label :is_profain %>

<%= i.check_box :is_profain %>

<% end %>

<%= submit_tag 'Create' %>

<% end %>

<%= link_to ‘Back’, words_path %>

// words_controller.rb
def create

@client_ip = request.remote_ip

  ActiveRecord::Base.transaction do
    @word = Word.new(params[:word].merge(:ip_address =>

@client_ip, :user_id => ‘1’))
@definition = Definition.new(params[:definition].merge
(:ip_address => @client_ip,
=> ‘1’,
=> @word.id,
=> ‘published’))
rescue ActiveRecord::RecordInvalid => invalid
flash[:notice] = ‘Word was not created’
render :action => “new”