# Transactions with two models

**URL:** <https://www.ruby-forum.com/t/transactions-with-two-models/108387>\
**Category:** Rails\
**Created:** [July 3, 2007, 12:26am UTC](https://www.ruby-forum.com/t/transactions-with-two-models/108387 "2007-07-03T00:26:28Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![dracos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ea666f/32.png) [@dracos](https://www.ruby-forum.com/u/dracos)\
**Post date:** [July 3, 2007, 12:26am UTC](https://www.ruby-forum.com/t/transactions-with-two-models/108387/1 "2007-07-03T00:26:28Z")

</div>

Hi,

In Agile Web D. with Rails section on Transactions (p 381)  
there are two main examples.

1. making changes in two records in the same database table
2. making changes in two records each in a different _database_

I want to do what is in between: changes in two records each in a  
different table of the same database. Suppose they are apples and  
oranges tables.

How do I write this?

Do I need to be as elaborate as this and will it work?

apple = Apple.find(:first)  
orange = Orange.find(:first)

Apple.transaction(apple) do  
Orange.transaction(orange) do  
apple.update\_attributes(params[:apple])  
orange.update\_attributes(params[:orange])  
end  
end

Or can I just write something much simpler like this?

Apple.transaction(apple, orange) do  
apple.update\_attributes(params[:apple])  
orange.update\_attributes(params[:orange])  
end

Will the above be a problem since orange is not an Apple?

In the rails docs there is something even simpler

transaction do  
apple.update\_attributes(params[:apple])  
orange.update\_attributes(params[:orange])  
end

but I think this version won’t restore the apple and orange instances  
back to their previous state if the transaction fails.

What I don’t understand is the class name that precedes  
“.transaction”. Does that class name make a transaction for just that  
table or with the entire _database_ associated with that table?

Any help greatly appreciated.

Thanks,  
Peter

---

<div class="post-metadata">

**Author:** ![dracos](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ea666f/32.png) [@dracos](https://www.ruby-forum.com/u/dracos)\
**Post date:** [July 3, 2007, 1:59am UTC](https://www.ruby-forum.com/t/transactions-with-two-models/108387/2 "2007-07-03T01:59:37Z")

</div>

On Tuesday 03 July 2007, Peter M. wrote:

> end
> 
> Or can I just write something much simpler like this?
> 
> Apple.transaction(apple, orange) do  
> apple.update\_attributes(params[:apple])  
> orange.update\_attributes(params[:orange])  
> end

Both versions are equivalent as ActiveRecord doesn’t do nested  
transactions. Transaction blocks only open a transaction if one is not  
already open.

> back to their previous state if the transaction fails.  
> True, but object-level transactions are deprecated and will disappear  
> some time in the future. From this, I take it, that they haven’t been  
> widely used. See the API docs for more info.

> What I don’t understand is the class name that precedes  
> “.transaction”. Does that class name make a transaction for just that  
> table or with the entire _database_ associated with that table?

The class has no more significance than that it is used to access the  
database connection. Commonly all classes share a connection to the  
same database, thus it doesn’t really matter which class you use here.  
You could even write ActiveRecord::Base.transaction { … }.

In cases where your model classes _are_ connected to different  
databases, you are out of luck regarding transactions, anyway, as  
ActiveRecord doesn’t ensure transactional consistency among multiple  
databases; there is no support for 2-Phase-Commit.

Michael

–  
Michael S.  
[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
[http://www.schuerig.de/michael/](http://www.schuerig.de/michael/)
