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.
On Apr 10, 6:42 pm, MohsinHijazee [email protected] 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.
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
How do I do that?
On Apr 10, 6:50 pm, Frederick C. [email protected]
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
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:
- 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
@[email protected]
@[email protected]
@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
- 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!! 