Saving Objects without Saving Objects

I have a problem that I think is probably fairly common but I haven’t
seem to be able to come up with the magic combination of search terms to
find a solution (or it really isn’t that common). Here’s the deal…

Scenario: A system allows a user to enter in articles via a web-form.
The system provides a preview function; not a live preview, but a
preview on another page where they can see what the article will look
like when posted. The system follow s the share-nothing approach.

Challenge: The article object, from the user’s perspective, is not saved
until she clicks the SAVE button. If the user clicks the preview
button, however, the article object needs to be stashed somewhere so
that the preview page can pick it up. Then when the user returns to the
edit page from the preview, the article object again needs to be
retreived. How do you save the object without really saving it?

P.S. - Storing the object in the session is not an acceptable solution.

I’ve handled this case so far by saving the object, but with a status
(an attribute of the object) of NEW. Then when the user ACTUALLY saves
the object, I change the status to SAVED. This works, but is a bit
cumbersome as all of the code that deals with objects like this needs to
be aware of this status.

Any help would be appreciated.

Regards.

Hi Jason,
You could either store the object in the params hash, and have the form
send it with a post request, or use the status method, which would allow
for saving drafts, and keeping more data about the status. I would go
with the status method, but you could send it in te params hash as well.
Good luck!

Jason F. wrote:

I have a problem that I think is probably fairly common but I haven’t
seem to be able to come up with the magic combination of search terms to
find a solution (or it really isn’t that common). Here’s the deal…

Scenario: A system allows a user to enter in articles via a web-form.
The system provides a preview function; not a live preview, but a
preview on another page where they can see what the article will look
like when posted. The system follow s the share-nothing approach.

Challenge: The article object, from the user’s perspective, is not saved
until she clicks the SAVE button. If the user clicks the preview
button, however, the article object needs to be stashed somewhere so
that the preview page can pick it up. Then when the user returns to the
edit page from the preview, the article object again needs to be
retreived. How do you save the object without really saving it?

P.S. - Storing the object in the session is not an acceptable solution.

I’ve handled this case so far by saving the object, but with a status
(an attribute of the object) of NEW. Then when the user ACTUALLY saves
the object, I change the status to SAVED. This works, but is a bit
cumbersome as all of the code that deals with objects like this needs to
be aware of this status.

Any help would be appreciated.

Regards.

Jason F. wrote:

I have a problem that I think is probably fairly common but I haven’t
seem to be able to come up with the magic combination of search terms to
find a solution (or it really isn’t that common). Here’s the deal…

Scenario: A system allows a user to enter in articles via a web-form.
The system provides a preview function; not a live preview, but a
preview on another page where they can see what the article will look
like when posted. The system follow s the share-nothing approach.

Challenge: The article object, from the user’s perspective, is not saved
until she clicks the SAVE button. If the user clicks the preview
button, however, the article object needs to be stashed somewhere so
that the preview page can pick it up. Then when the user returns to the
edit page from the preview, the article object again needs to be
retreived. How do you save the object without really saving it?

P.S. - Storing the object in the session is not an acceptable solution.

I’ve handled this case so far by saving the object, but with a status
(an attribute of the object) of NEW. Then when the user ACTUALLY saves
the object, I change the status to SAVED. This works, but is a bit
cumbersome as all of the code that deals with objects like this needs to
be aware of this status.

You can construct the object and display it in the request that handles
to form input, without saving. If the edit form is included on the
preview page this will work fine, this is how rails scaffolding works.

def new
@post = Post.new
end

def create
@post = Post.new(params[:post])
end

If you want a slightly more permanent solution, you can use flash.
Although it technically uses the session, it’s automatically purged one
request after it’s set. This should allow your form to post to the
preview page, then the user can click a link that takes them back to the
edit form, and it will have all the proper data in the fields since it’s
reading form the object in the flash instead.

def post_form
@post = flash[:post] || Post.new
end

def preview
@post = Post.new(params[:post])
flash[:post] = @post
end

Although with either of these solutions if the user goes anywhere else
from the preview page the data will be lost. If you want any long term
access to “unsaved” records then they have to be saved SOMEWHERE. If
this is the case, you current solution is probably best with saving the
record anyway and then marking it as saved later.

If you only need to keep the data around for 1 intermediate request
(i.e. to the preview page and back) then the flash should work fine.

On 7/7/06, Alex W. [email protected] wrote:

Challenge: The article object, from the user’s perspective, is not saved
the object, I change the status to SAVED. This works, but is a bit
end
reading form the object in the flash instead.
Although with either of these solutions if the user goes anywhere else
from the preview page the data will be lost. If you want any long term
access to “unsaved” records then they have to be saved SOMEWHERE. If
this is the case, you current solution is probably best with saving the
record anyway and then marking it as saved later.

If you only need to keep the data around for 1 intermediate request
(i.e. to the preview page and back) then the flash should work fine.

Another solution that we use is to have a totally seperate table with
draft articles, there’s never a worry that the drafts will get out
unless they’re copied over and you don’t have to worry about the
overhead of a conditional on each query. With MySQL 5 this is less of
a problem due to the muuuuuch improved range optimizations though so
having an attribute seems like a decent, easy to understand approach.

Cheers,
Chuck V.

Thanks for all the great feedback!

I do need to keep the object around in my real problem for more than one
request. The actual object is built up over a series of steps (in
wizard fashion). The preview feature is also available at any step.

So, it sounds like the approach I’m taking is not way afield. I like
Chuck’s idea of having separate tables for the “draft” objects. My only
concern is that in my particular problem space I have several of these
types of objects, so I’d end up with a bunch of extra tables; not the
worst thing in the world, however.

There is also the question of cleaning up “drafts” that the user never
revisits. In my application, introducing the concept of a “draft” in
the UI to the user wouldn’t make sense for these types of objects (the
objects are not really articles). I guess I could just add the clean-up
of drafts to the task that cleans up expired sessions.

Thanks again for the feedback.

Regards