Problem with Complex Form Saving

I'm having a problem with a fairly complex form, with data from multiple
models.

I've trimmed down the code to the bare minimum ...

=========== START OF MODELS =============
class Order < ActiveRecord::Base
   has_many :order_products
   has_many :card_transactions
   belongs_to :purchaser, :class_name => 'Party', :foreign_key
=> "purchaser_party_id"
   belongs_to :recipient, :class_name => 'Party', :foreign_key
=> "recipient_party_id"
end

class Party < ActiveRecord::Base
    has_many :purchaser_orders, :class_name => 'Order', :foreign_key
=> 'purchaser_party_id'
    has_many :recipient_orders, :class_name => 'Order', :foreign_key
=> 'recipient_party_id'
end

class OrderProduct < ActiveRecord::Base
        belongs_to :order
        belongs_to :product
end

class CardTransaction < ActiveRecord::Base
    belongs_to :order
end
========== END OF MODELS ====================

You'll notice that I have two references to Party from Order : the purchaser
and the recipient.

Now here is the controller -

========== START OF CONTROLLER ==================
class OrdersController < ApplicationController
....
  def new
    @orders = Order.new
    @purchaser = @orders.build_purchaser
    @recipient = @orders.build_recipient
    1.times { @orders.order_products.build }
    @card_transaction = CardTransaction.new
  end
....
def create
    params[:orders][:last_updated_timestamp] = Time.now
    params[:orders][:last_changed_user_id] = '100'
    params[:orders][:order_status_id] =
OrderStatus.find(:first, :conditions => ["order_status_desc = ?", 'Phone
Unprocessed']).id
    params[:orders][:account_id] = '100'
    if !params[:delivery_time_before].nil? then
      params[:orders][:delivery_time_before] = params[:delivery_time_before]
[:hour_minute] + ":00"
    end
    if !params[:delivery_time_after].nil? then
      params[:orders][:delivery_time_after] = params[:delivery_time_after]
[:hour_minute] + ":00"
    end

    @orders = Order.new(params[:orders])
    @orders.wire_service_id = params[:wire_service_id]

    params[:card_transaction][:transaction_timestamp] = Time.now

    # @purchaser = @orders.build_purchaser(params[:purchaser])
    # @recipient = @orders.build_recipient(params[:recipient])

    @card_transaction = CardTransaction.new(params[:card_transaction])
    @purchaser = Party.new(params[:purchaser])
    @recipient = Party.new(params[:recipient])

    @orders.transaction do
      @purchaser.save
      params[:orders][:purchaser_party_id] = @purchaser.id
      @recipient.save
      params[:orders][:recipient_party_id] = @recipient.id

       if !@orders.save
         render :action => 'new'
         return
       end

       @card_transaction.order_id = @orders.id
       @card_transaction.transaction_amount = @orders.order_price_total
       @card_transaction.credit_card_type_id = params[:credit_card_type_id]
       if @card_transaction.save
         flash[:notice] = 'Order ' + String(@orders.id) + ' was successfully
created.'
         redirect_to :action => 'queue'
      else
         render :action => 'new'
         return
       end
    end
  end
...
end
================== END OF CONTROLLER ===================

When I call the create method, I get records in ORDERS, CARD_TRANSACTIONS and
ORDER_PRODUCTS. But no records in PARTIES and the recipient_party_id and
purchaser_party_id in ORDERS are both null.

I'm totally lost !!!

Any help gladly appreciated.

Thanks

    @orders.transaction do

This is what will be messing you up I think.

http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

Wouldn't it be "Order.transaction do..."

?

Also, a transaction will only fail and roll back if an exception is
raised within the block, none of your .save commands are using .save!
so they will return false, not raise an exception if they fail. You
might want to change this.

Mikel

Mikel,

Unfortunately that isn't the problem, although what you have suggested is
better.

I know about save! and was intending to change that.

When I did this, it started to give me clues -

ActiveRecord::RecordInvalid (Validation failed: Last name can't be blank):

The fact that the column is "surname" and the model validation has "last_name"
was the problem there !!!

Anyway, the party records are now being saved ... but I still was not getting
the IDs into Orders.

Then I noticed that I was loading up the params[:orders] AFTER I'd loaded the
@orders local variable with this. Changing -

params[:orders][:purchaser_party_id] = @purchaser.id

to

@orders.purchaser_party_id = @purchaser.id

and everything now works !!!

Thanks for the pointers.

Phil