Well, yes and no.
No I never figured out the exact problem, but yes I worked around it,
and actually ended up with a better application because of it!
My main solution was that I stopped storing any kind of *active
record* object in session. Instead I only store id's in session and
retrieve the object from the database when it is required.
For things like wizards it was a little more complicated. I developed
a technique that I quite liked, but isn't totally DRY. I created an
extra model in my application called xyz_builder. So if you are
building an account it would be called account_builder. This allowed
me to completely separate complete and incomplete accounts, so I don't
need to worry about checking conditions every time I deal with
accounts.
This had a few other useful side effects:
- I can now save all changes made to builders without worrying about
consequences, which makes the wizard more usable.
- I can define a lot more wizard based logic and keep it separate
from the account model. E.g. I defined separate validation methods for
each step such as step_one_complete? So you can do whatever you want
in the controller and the view based on which steps are complete.
- It became much easier to test the creation of accounts and the
wizard through unit tests
and finally my controllers became very thin:
def step_1
if
request.post?
account_builder.update_attributes(params[:account]) #
account_builder is a method that fetches the correct builder
redirect_to :action => :step_2 if account_builder.step_1_complete?
end
end
def step_2
if
request.post?
account_builder.update_attributes(params[:account])
if account_builder.complete?
account = account_builder.create_account
redirect_to :action => :show, :id => account
end
end
end
Note: I just made up this example, so there may be errors, but it's
essentially what my controllers ended up looking like.