On May 1, 2008, at 3:41 , Robert W. wrote:
Never mind. I think I see the problem now. You need the document to be
created when and only when the offer creates successfully, and you
also need the offer to roll back if the document creation fails.
That’s right.
Is your create_document method inside of the Offer model class or is
it in a different class? The observer allows you to move this rather
unrelated code outside of the model object (since creating the
document is not a direct responsibility of the Offer model class).
Well in this case an offer knows how to generate its own document.
Note than an observer as far as this problem is concerned is not much
different than a regular AR callback. I mean, the techique that does
not work is after_*, no matter whether it is in the model or in an
observer.
after_* does not work for what I need because the offer is not aware
of whether it needs to save a document or not, so I can’t put the
conditional in the callback. I think I can revise that, but even if it
knew it you can’t rollback the INSERT in an after_create, you can
abort in before_*s. Well you could raise an exception in after_*s, but
that’s unexpected behaviour because you do not expect @offer.save to
raise an exception like that.
So what I do with rollback_active_record_state! is basically what AR
does, plus catching exceptions from document generation. With that
code I can implement the transaction I need, have @offer (almost)
restored, and return a controlled boolean as usual.
if @offer.save_and_generate_document
# …
end
I think leaving timestamps with the new values is a bug. I mean, a
new_record? shouldn’t have a timestamp in created_at, I can live with
that though I’ll try to determine if that’s a bug and fill a ticket if
that’s the case.
Thank you for helping Robert.
– fxn