views:

49

answers:

1

I'm trying to build a user sign-up page that will span three pages and create two records, a user object and a ticket object:

  • the first (index) collects just one summary field of the problem.
  • the second (signup_a) collects the detail description of the problem, autopopulates the summary from previous, a few associated details that will go in the ticket object, and the firstname/lastname/email that will go in the user object
  • the third (signup_b) adds more detail to the user object such as address, city, state, etc. but no more details are added to the ticket object, so it could be closed out here.
  • the final page (signup_c) displays all the user/ticket details back to the client and saves after a confirm button.

Currently, I have the methods in a single controller (code simplified without error-checking or respond_to):

def index # Collects summary
@ticket = Ticket.new
end

def signup_a # Basic Ticket Info/User name and email
    @ticket = Ticket.new(params[:ticket])
    @user = User.new
end 

def signup_b # Address and other misc. pref's
    @ticket = Ticket.new(params[:ticket])
    @user = User.new(params[:user])
end

def signup_c #Display final results
  @ticket = Ticket.new(params[:ticket])
  @user = User.new(params[:user])
end     

def submit_ticket #Saves info
  @ticket = Ticket.new(params[:ticket])
  @ticket.save!
  @user = User.new(params[:user])
  @user.save!
end

The problem is... I don't want to save info into the DB at every single step, only the last, but the variables from each page before that aren't explicitly referenced in the next page aren't being passed. How do I keep adding to the Ticket and User objects so the info stays until the very last page where I do one save! ? Also, when I perform a @user.save! method... can I still call on the individual attributes from the instance or does performing a save! turn the object into a true/false value based upon whether the info was stored?

A: 

Instead of saving to the DB with each intermediate step, save the posted info to a session.

def signup_a
   session[:ticket] = params[:ticket]
end

Then, when you get to the end, you can retrieve that data from the session to pass to the object constructors.

def submit_ticket #Saves info
  @ticket = Ticket.new(session[:ticket])
  @ticket.save!
Legion
for signup_b and c wouldn't i need to do something like session[:ticket] << params[:ticket]or something? It would seem that that would just overwrite the previous step?
Kevin
Also, I've heard storing model objects in session is bad?
Kevin
Rather than overwriting session[:ticket] in the "b" and "c" steps, you can add the individual elements from those pages to the existing session[:ticket] object, i.e. "session[:ticket][:field1] = params[:ticket][field1]", etc.
Legion
You're not storing the model object in a session. You're storing the values of the POSTed forms to build up a complete list of parameters, which you'll then pass to the model constructor.
Legion
Thanks Legion, I appreciate your help. Last question, is there a way to do that for subsequent forms so I wouldn't be hard-coding specific variable instances in the controller or model logic so if the DB changes, I don't have to change the specific variable assignments?
Kevin