# Problem with Complex Form Saving

**URL:** <https://www.ruby-forum.com/t/problem-with-complex-form-saving/131872>\
**Category:** Rails\
**Created:** [March 14, 2008, 12:27am UTC](https://www.ruby-forum.com/t/problem-with-complex-form-saving/131872 "2008-03-14T00:27:21Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Philip\_N](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c5a1d2/32.png) [@Philip\_N](https://www.ruby-forum.com/u/Philip_N)\
**Post date:** [March 14, 2008, 12:27am UTC](https://www.ruby-forum.com/t/problem-with-complex-form-saving/131872/1 "2008-03-14T00:27:21Z")

</div>

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

Philip N.  
ScotDB Limited  
(removed\_email\_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Philip\_N](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c5a1d2/32.png) [@Philip\_N](https://www.ruby-forum.com/u/Philip_N)\
**Post date:** [March 14, 2008, 12:34am UTC](https://www.ruby-forum.com/t/problem-with-complex-form-saving/131872/2 "2008-03-14T00:34:23Z")

</div>

> ```
> @orders.transaction do
> 
> ```

This is what will be messing you up I think.

> **[ActiveRecord::Transactions::ClassMethods](https://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html)**
>
> Active Record Transactions Transactions are protective blocks where SQL statements are only permanent if they can all succeed as one atomic action.

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

---

<div class="post-metadata">

**Author:** ![Philip\_N](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/c5a1d2/32.png) [@Philip\_N](https://www.ruby-forum.com/u/Philip_N)\
**Post date:** [March 14, 2008, 1:31am UTC](https://www.ruby-forum.com/t/problem-with-complex-form-saving/131872/3 "2008-03-14T01:31:50Z")

</div>

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

On Thursday 13 March 2008 23:33:44 Mikel L. wrote:

> 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

–  
Philip N.  
ScotDB Limited  
(removed\_email\_address@domain.invalid)
