quick search:
 

make actions show up in UNDO log

Submitted by: slinkp
Last Edited: 2004-01-12

Category: Product Development

Average rating is: 4.0 out of 5 (1 ratings)

Description:
Sometimes a product method or External Method is used to mutate objects
(which are not instances of the Product). When you do this, your
transaction is not automatically available in the Undo log. This recipe
shows how to put it in the undo log.


Source (Text):
# assume foo is the object whose undo log should show this transaction.
>>> path = '/'.join(foo.getPhysicalPath())
>>> comment = 'Descriptive text about this transaction'
>>> get_transaction().description = '%s : %s' % (path, comment)
>>> get_transaction().setUser('paulw')
>>> get_transaction().commit()

Explanation:
The above source is taken from a debugging session, but the principle applies
in Product development too. You want to get a handle to the
current transaction, modify its description attribute, and be sure
to set the user correctly too. (The user should be set automatically
when your code is invoked by a web request, but in a debugging
session you have to do it explicitly.)
get_transaction().setUser() takes a string argument, not an
actual User object.

To call get_transaction() in a Product method, I think you only need
to have imported ZODB first.

The important thing about the description is that it must start
with the path to the object. get_transaction().note() can also be used to change the description, but only
by appending to it. If any previous part of the transaction has set anything in the
description, you'll have to modify description directly as shown in the
recipe above.

Be careful about which object's physical path you use!
If your transaction modifies a bunch of objects, pick one
object that makes sense as a place to put the undo information for
all of them.

You do not need to call get_transaction().commit() in Product code,
it's done automatically when your method succeeds.

You don't need this recipe if your product method is only mutating the current product
instance; in that case,the usual base classes will do the job for you. (I am not
sure which base class!)

More information:
http://www.zope.org/Members/mcdonc/HowTos/transaction


Comments:

Small change to make transaction appear in specific object's Undo log by alecm - 2004-01-11
The transaction description needs the object path at the very 
begining in order to show up in the correct place.  The 
get_transaction().note() method unfortunately only appends to the 
transaction description.  So unless a new transaction has been 
started (by ending the existing transaction with an explicit 
commit()) appending the path using note() will not associate the 
transaction with the proper object.  Instead you can directly alter 
the description attribute of the Transaction object to get what you 
need: 
 
get_transaction().description = '%s : %s'%( 
	'/'.join(foo.getPhysicalPath()), description) 
 
Re: Small change to make transaction appear in specific object's Undo log by slinkp - 2004-01-12
Thanks, I wondered why it seemed kind of flakey :-)

Just to clarify, is "description" the previous value of the transaction's description? e.g.:

descr = get_transaction().description
path = '/'.join(foo.getPhysicalPath())
get_transaction().description = '%s : %s' % (path, descr)
 
Re: Re: Small change to make transaction appear in specific object's Undo log by alecm - 2004-01-12
Sorry I was unclear about that, especially with the duplicated name.  
The 'description' can be whatever string you want to use to describe 
the transaction.  You could use the old 
'get_transaction().description' for this, but it would include the 
original (probably unwanted) path.  Also, the auto-generated 
descriptions don't have much in the way of useful content.  The only 
thing that seems to matter is that you set the first string in the 
description to the path of the proper object, everything else is up 
to you (the ':' I added is entirely optional, for me it adds better 
readability).  So you could use something like this: 
 
description = 'Changed foo.bar from 35.0 to 25.0; Changed foo.Title 
to "BarBaz"' 
 
Or whatever you might find useful. 
 
Re: Re: Re: Small change to make transaction appear in specific object's Undo log by slinkp - 2004-01-12
Thanks very much Alec, I am updating the recipe with your improvement.