views:

2360

answers:

3

I'm having a quite complex model with many fields, has_many associacions, images added by image_column etc...

New object will be added by multi page form (8 steps) - how shoud I accomplish validation and propagation between those steps?

I think validation_group could be useful for defining validations for each step, what about overall design?

+3  A: 

For overall design, you might want to look into the concept of a Presenter layer (Jay Fields defines it in his blog entry Rails: Presenter Pattern) as a way to keep your controllers thin and views stupid when dealing with complex/multiple models.

Michael Sepcot
A: 

You could have a series of methods, e.g. step_1, step_2, and each one checks to see that the necessary data from the previous step was submitted. You could store data in the session so that, for example, step 3 would still have access to all the data collected and parsed in step 1. In the final step, put all the data that you've stored in the session plus the data from the penultimate step to use, and create a new row in the database or whatever you're gathering the data for. If a user messes up a step, redirect them to the previous step and fill out the form for them with the data they did fill out; e.g. if the user messes up step 2 and submits the form leading to step 3, catch the problem in your step_3 method, redirect the user to the step_2 method, and be sure the form elements in step 2 are pre-filled.

If you don't want to store data in the session as you go, you could create a new database row after the user has submitted step 1 and just update the fields in that row as you gather new data in each successive step. You could have some flag for 'complete' on the row, initially setting it to 0 and then setting it to 1 after the user has successfully completed all the steps.

You could also allow users to go to previous steps (e.g. let the user return to step 3 when he is on step 5).

Say your first step has a form with fields 'name' and 'email'. In your step_2 method, you should verify that params[:name] and params[:email] were passed and are valid. Store those in the session or a database row, however you chose. Then in step 2, you have a form with fields 'age' and 'gender'. In your step_3 method, you should verify that params[:age] and params[:gender] were passed and are valid, and you also need to ensure that the user has completed step 1, to prevent a user from entering the URL to access step 3 directly. And so on.

Sarah Vessels
A: 
class Campaign < ActiveRecord::Base
    with_options(:if => lambda { |campaign| campaign.on_or_past_step(:spam_can) }) do |spam_can|
      spam_can.validates_associated  :spam_can
      spam_can.validates_presence_of :spam_can
    end
  def on_or_past_step
   :
   :
  end
end

this is a work in progress, but i feel like I'm on the right track. I'm using AASM states to determine which validations to run. I still haven't worked out how the routes should work, as the model in question in my case is a resource. for example, which group of fields should be the edit action?