Keep some information between different "new" forms - ruby-on-rails

I have a form where the user can choose options from a lot of select boxes. The form is used to register several items from an RSS feed. The user fills in the form, clicks create and is presented with the same form for the next item in the list.
Sometimes, the same options are valid for several items in the list, and I would like to be able to save some of the selections done so the user doesn't have to make the same selection for the next items.
What is the best way of doing this? I've identified four ways of doing it:
Sessions
Just keep the values in the session hash. This will of course work and is very simple, but I have some undefined feeling that it is a bad idea. It will also not work if the user is using the form from different tabs in the browser.
Cookies
Basically the same as keeping them in the session, I think.
Profile
Can't be done in this case I believe, since profiles are shared between several users.
Database
The most complex way I've come up with is to keep the information in the database and use a query parameter to keep track of which information should be used. This is probably overkill, but in some ways the best way to me. I don't like the idea of keeping this kind of state in session or cookies.
Am I missing some way? Or something?

If after filling first form, some data is saved to db (object is created) then you can use this data from db to fill up new form.
If after filling first form, nothing is saved to db, then you can create in memory some objects based on params from previous post and based on this (on just on params) you can prepare new form. But of course data from previous form should be added as hidden fields in second form.

Related

Temporary Persistence when Dealing with MVC and Entity Framework

Perhaps it is my lack of experience still with really stretching MVC and Entity Framework but I've run into a problem I can't really figure out.
Up until now my applications have been simple: I show and hide a few divs in a View, and when the user has entered all data they hit submit and I save it to the database using EF. The complication I have now is I have basically have to have a flow where:
Person Registers -> Register Another Person? If Yes -> Person Registers -> And So On...
EDIT* To Clarify: Person comes in to Register a group of people. The first screen is a form where they enter identification info, next is clicked, and then They are asked if they'd like to add someone else, if they click yes they repeat that process. I create a Registration Object each time this happens until they don't want to add anymore, after which they are directed to a "Confirmation" action that shows them their registrations and let's them submit their registrations.
I need to have a way to temporarily hold that data while the user jumps to different actions and ultimately submits it to be saved. I'd prefer not to hold a bunch of models in a Session variable.
Well, in your given example, you shouldn't be holding on to anything. After each person is registered, that data can be saved to the database immediately before redirecting back to the form to allow the user to register another person. At each step, you're dealing with a discrete unit, so there's no reason not to just save it immediately.
In a different scenario, perhaps something like a wizard, where you collect partial info in multiple steps, which culminate to produce one discrete unit, your only real option is to use something like TempData. TempData is still session-based, and uses the Session object under the hood, but it does have the advantage over traditional use of Session that the data is only persisted through the next request, whereas Session data is persisted for the life of the session, which can be anywhere from minutes to weeks based on configuration.

MVC How to collect additional information based on what's changed in a form

I'm still on the conceptual stage of this problem, so I'm open to suggestions on how to go about solving the problem. The problem is this:
I have a web form. Users are editing data. When they submit the changes, I need to determine which fields are different, and then collect additional information for each field, like, find out why they changed a value.
I'm not allowed to use javascript to handle this task because some users will have javascript disabled.
So, how do I request additional information based on information already submitted, and how do I keep all the information straight so I can submit it all to the database correctly once it is all collected?
I can see submitting the changes, and then in the controller checking against the database (or hidden fields previously given to the view) to figure what fields are different, but then I don't know how to request additional information of the user based on that.
I agree with the approach of checking against the database to see which fields have changed (if you use hidden inputs remember that those can be tampered with - if your application is critical you'll want to avoid that). Once you know that something has changed, I would persist the new user input somewhere (disk, session, database, etc) so that you can access it later to actually persist it in the existing record in the database.
If you need to request additional information, once you've stored what the user submitted just return another view and form for the user to submit back to you. Depending on what your needs are, if you need to get a description for each field, perhaps just build a collection of fields that have changed and iterate over that collection in the view to ask for input.

Ruby on Rails: Two views, one save buffer

Just a note before you read this, I'm not a programmer in RoR but I just wanted to validate that this is possible, so sorry in advance.
I have a quick question about using a secondary page. Here's how I want it to work:
I have a primary page that has some data that will be saved. I have a link to a secondary page that you save only to the buffer. This means that if I change it three times everytime i go back to look at it it shows the last value I changed it to.
At save time of the primary page, I want the information on the primary page and the secondary page to be validated and saved. If it fails, I don't want to save the information on either page. Is this possible in RoR? If so can someone explain to me how?
You could do this in a few ways:
Have one real page, but use JavaScript to hide and show parts of it as needed.
Store the object in the session, and only write it to the database at the end
Store the data in a temporary table and save it in the real table at the end

Storing Product List through out session

Im using MVC ASP.NET C#, jQuery
I'm building what could be decribed as the simpliest shopping cart in the world.
Basically My Clients wants users to be able to browse the site, Click on a product they want and it be added to a "list" and then when they "Checkout" they simply fill in a form and it emails my client with the list of products they had chosen!
I was thinking of something like storing them in a cookie. So as the user browses they won't be lost, Then have a jQuery dialog appear when they choose to view/checkout their cart. and it can list all products and then they simply fill in a simple form..
Is this the best way to go about it. Its a cheap website and I would like the simplest way to do this? All i guess I would need to sort is the product Id's..
Any ideas of better ways or any opinions at all!
Using Session depends on whether you think the users will pick the products in one go. Or will they leave the page and come back in an hour? The problem being that if they come back in an hour, the Session State may have been garbage collected to free up resources on the server, or the session might have expired.
To get around this, if all the products are on one page, you could store the chosen products in a hidden field, encrypted and all, that will stay there until the user closes the app.
You just need to serialize the list of product Ids, pass that serialized string to the view and put it in a hidden field.
Another option would be to store it in the users session. A benefit of this is if the user has cookies turned off and the site caters for cookieless session state then they will still be able to select products and checkout.
The thing to look out for is how much you could potentially end up storing in session. From the sounds of it this will not be an issue but if this could potentially use up an unacceptable amount of memory then you would probably need to consider a database approach anyway rather than cookies.
I'd say to go for the Session object. You can always configure the location of Sessions at runtime
I think some may dislike this storage method (it breaks testing isolation, if i'm not mistaken), but it's there for free :)
If you're using jquery, you could store the basket as a json array inside the $('body').data() element (or actually as i do, under a div called '#storage'). this works as a fantastic local storage mechanism, tho' would only be relevant to the current page that the user was on and would be cleared on moving to subsequent 'new pages' unless of course, your design was such that the shopping page was ALWAYS the same page and only refreshed by ajax methods. this way, you could continually append/modify the json structure on the 'worksurface' page.
i use this technique for a different application of the logic, but virtually for the same reason.
here's a snippet of the kind of thing i do:
/* example of data params key*/
var keyParams = "Data-Search-type-" + $('#searchtype').val();
/* add json to body with key*/
$('#storage').data(keyParams, jsonData);
/* get same data back later */
var jsonData = $('#storage').data(keyParams);
When i 'save' the data to the server, i then clear the data() element back to null. There is of course the other option of localstorage itself which can be used well, especially in disconnected environments (such as mobile apps).
another way to skin the many skinned cat!!

ASP MVC - confirm page when adding object to database

I'm making a simple CRUD app with ASP MVC and I want to have a confirm page when creating a new object and inserting it into the database.
The problem is that I'm having trouble passing the object between actions. I tried to save it in the session after it's created and then retrieving it when the user confirms, but I'm getting an InvalidOperationException when I try to insert it into the database ( I'm using Entity Framework )
I'm not even sure if I'm approaching this the right way. Any ideas?
What I like to do if the schema allows for it, is to have an active flag (and timestamp field) on the record. You insert on the first page without setting that flag. The confirm page merely sets the active flag. Another process can clean dead records that were not confirmed within a certain range of their timestamp. And the object or entity never ties up session memory.
edit for clarity: as a result you only pass the id of the created entity to the confirm page
Tim's is the best basic answer to this but if you don't want to include the extra logic you could also consider using hidden fields on the confirm page so confirming actually resubmits the form data (this means less DB trips and means that you don't have old unconfirmed entries sitting in the DB to filter out but means more data to and from the client).
Another alternative that might be preferred from a UI point of view is to have Tim's answer but if JavaScript is enabled make the submit button instead pop up a confirm screen, clicking OK would submit both the form and the confirmation in one go.

Resources