From: Julian Fitzell Date: 2004-05-08T05:33:02+09:00 Subject: Re: What is Borges? Carl Youngblood wrote: > >> We use this in seaside (and borges does the same) to allow the user to >> use the back button in the browser. No matter how many times the user >> goes back and clicks a link on the same page, the handling will always >> be done by the exact same execution context. It doesn't know it's being >> called over and over; it just knows it's supposed to handle the clicks >> generated from that page and it always does. > > > Is that always good? What if it means the users ends up clicking on the > purchase button twice and we charge their card twice? I've always > thought that it was best not to let the user use the back button in > cases like these (i.e., forward them to the right page, display an error > indicating that the posted values are stale, or something like that). No, it's not always good. But it's always good to be able to. Seaside (and I believe Borges for Ruby implements this piece too) has a concept of transactions or isolate blocks. The way this works is that you execute a section of code inside a block. When that block terminates, all the pages in that session get expired. So in the case of a shopping cart, you would likely start an isolate block when they begin the payment process and expire all those pages as soon as they press "Purchase". Note that you also have control over which pieces of state get backtracked with the back button. So you can have the UI state representing, for example, which tab is selected roll back with the back button, but leave your model data (such as the shopping cart contents, perhaps) so it always represents the newest data. It requires some thought in each case to determine what the desired semantics are, but once you decide what you want it's easy to implement either way. Julian