# Rails Transactions

**URL:** <https://www.ruby-forum.com/t/rails-transactions/134405>\
**Category:** Rails\
**Created:** [April 10, 2008, 3:43pm UTC](https://www.ruby-forum.com/t/rails-transactions/134405 "2008-04-10T15:43:11Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [April 10, 2008, 3:43pm UTC](https://www.ruby-forum.com/t/rails-transactions/134405/1 "2008-04-10T15:43:11Z")

</div>

Hi!  
I am confused about Rails transactions… Look at the following  
code:

# CODE BEGINS

def save\_instances(entity\_id, instance\_resources)  
# This contains the instance ids of the newly created instances  
instance\_ids = []

```
Instance.transaction do
  instance_resources.each do |instance_resource|
    instance_ids << save_instance(entity_id, instance_resource)
  end
end

return instance_ids

```

# end CODE ENDS

Now the save\_instance method is like this:

def save\_instance(entity\_id, instance\_resource)

```
  instance = Instance.new(:entity_id => entity_id).save!

  detail_ids = get_detail_ids(entity_id)

  instance_resource.each do |detail_name, values|
    save_all_values(instance.id, detail_ids[detail_name], values)
  end
return instance.id

```

end

And similarly, there is save\_all\_values method which does a bit more  
work. But support for transactions is not working at all. i.e. if an  
exception is raised by the methods beneath, the records created  
earlier are not rolledback.

I am only starting a single transaction block in the first method so  
what’s wrong with all this?  
BTW, I am using PostgreSQL 8.2 as backend.

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [April 10, 2008, 3:49pm UTC](https://www.ruby-forum.com/t/rails-transactions/134405/2 "2008-04-10T15:49:07Z")

</div>

On Apr 10, 6:42 pm, MohsinHijazee [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ==========  
> save\_all\_values(instance.id, detail\_ids[detail\_name], values)  
> I am only starting a single transaction block in the first method so  
> what’s wrong with all this?  
> BTW, I am using PostgreSQL 8.2 as backend.

Note that this is happening in tests. I mean tests are getting failed.

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [April 10, 2008, 3:52pm UTC](https://www.ruby-forum.com/t/rails-transactions/134405/3 "2008-04-10T15:52:03Z")

</div>

On 10 Apr 2008, at 14:48, MohsinHijazee wrote:

> > I am only starting a single transaction block in the first method so  
> > what’s wrong with all this?  
> > BTW, I am using PostgreSQL 8.2 as backend.
> 
> Note that this is happening in tests. I mean tests are getting failed.

Tests are special. Because each test itself is wrapped in a  
transaction by default and because rails does not support nested  
transactions you cannot test your handling of transactions. If you  
want to do that you need to turn off transactional fixtures.

Fred

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [April 11, 2008, 1:37pm UTC](https://www.ruby-forum.com/t/rails-transactions/134405/4 "2008-04-11T13:37:03Z")

</div>

How do I do that?

On Apr 10, 6:50 pm, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [April 11, 2008, 2:26pm UTC](https://www.ruby-forum.com/t/rails-transactions/134405/5 "2008-04-11T14:26:38Z")

</div>

On 11 Apr 2008, at 12:36, MohsinHijazee wrote:

> How do I do that?

set self.use\_transactional\_fixtures = false (either in your  
test\_helper.rb which will do it for all tests or just in one of of  
your test files)

Fred

---

<div class="post-metadata">

**Author:** ![MohsinHijazee](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e68b1a/32.png) [@MohsinHijazee](https://www.ruby-forum.com/u/MohsinHijazee)\
**Post date:** [April 16, 2008, 5:56pm UTC](https://www.ruby-forum.com/t/rails-transactions/134405/6 "2008-04-16T17:56:48Z")

</div>

Frederick C. wrote:

> On 11 Apr 2008, at 12:36, MohsinHijazee wrote:
> 
> > How do I do that?
> 
> set self.use\_transactional\_fixtures = false (either in your  
> test\_helper.rb which will do it for all tests or just in one of of  
> your test files)
> 
> Fred

OMG,

you do not understand how that just fixed my life. Seriously! I’ve been  
bummed out all week cuz my functionals that dealt with transactions were  
not working properly. I was trying to assert counts after my controllers  
would throw an exception in a transaction and they never matched up.  
Even though I searched and read bug filings on a bunch of AR stuff in  
the Rails Trac server, I _still_ couldn’t figure out what was going  
wrong because I didn’t remember having this prob on my previous Rails  
projects.

So to recap and spell it out in case someone else stumbles upon this and  
doesn’t yet get it:

1. Your controllers have something like

def create

# assign your params to person, address, credit card

# don’t get caught up on the model details as the below

# probably isn’t the best object graph

# And I know, this is straight outta the agile rails book pp. 492-493

Account.transaction do  
@credit\_card.address=@address  
@account.address=@address

@address.save!  
@credit\_card.save!  
@account.save!  
end

flash[:message]=‘Update successful.’  
render :action=\>‘show’

rescue Exception =\> ex

@account.valid?  
@credit\_card.valid?  
@address.valid?  
render :action=\>‘new’

end

1. Your tests have something like

def test\_add\_credit\_card  
count = CreditCard.count

# do your post, rollback should happen in logs

assert\_not\_nil assigns(:credit\_card)  
assert\_equal count, CreditCard.count

end

This totally made my week. Thank you!! 🙂
