Rubytastic
Rubytastic

Reputation: 15501

update a model from another controller without passing an id?

Im trying to update my profile model true a welcome_controller. The reason for this is that I have some steps as a welcome wizzard were the user builds his initial profile.

I cannot get the routing correct, since im not supplying an id.

routes.rb

  match "/welcome/:step" => "welcome#edit"
  match "/welcome" => "welcome#edit"
  resources :welcome

welcome_controller update and edit actions:

    def edit
    # form updates post to edit since
    # profile is non existant yet

    params[:step] = "photos" unless params[:step]
    @photos   = Photo.where(:attachable_id => current_user.id)
    @profile  = Profile.where(:user_id => current_user.id).first
    @photo    = Photo.new


    if ["photos", "basics", "details"].member?(params[:step])
      render :template => "/profiles/edit/edit_#{ params[:step]}", :layout => "welcome"
    else
      render :action => "/profiles/edit_photos"
    end

    end

  # update profile attributes then update the correct step
  def update

    raise('welcome update called')
    @profile = Profile.where(:user_id => current_user.id).first
    @profile.update_attributes(params[:profile])

    case params[:step] # update the steps
      when "photos"
        current_user.update_attributes(:welcome => 1)
      when "basics"
        current_user.update_attributes(:welcome => 2)
      when "details"
        current_user.update_attributes(:welcome => 3)
    end

    # redirect to welcome_path before_filter determine step
    redirect_to welcome_path
  end

the forms for photo, basic and details are just a form_for @profile So im posting it to profile but want to post it to the welcome controller instead :(

Whats the best way to approach this ? Totally stuck on this

Upvotes: 0

Views: 228

Answers (1)

m_x
m_x

Reputation: 12564

There are a couple of approaches available to this problem.

  1. Use the session. Every step would run a couple validations, and then update a set of serialized params stored in session, until the final step is reached. I'm not a big fan of this one, but it works for simple apps.
  2. Use a single form, with some js/css tricks (tabs, "slideshow-like" pages with "next" & "previous" buttons) to make your form feel less cumbersome. This is not applicable to all problems, but i find that many times multi-step forms do not really need multiple round-trips and are juste a way to make the UX better.
  3. Serialize all params from previous steps as hidden input fields. Not quite a good idea, but again, it can "just work" for small apps.
  4. Create a "multi-step form" model, as a state machine with different validations for each state. At each step, save the model (either in the db, or in a memory cache) so you have an id you can provide to the next form. Each successful save would also change the state to the appropriate step. The problem with this approach is how to deal with "abandoned" forms, that you have to destroy somehow (using a cron job to clean the db, or using your memory cache expiration settings).

Upvotes: 1

Related Questions