3

I'm trying to implement the 'Wicked' gem for wizards and cannot figure out this error for the life of me. Already referenced Ryan bates railscast #346 and the step by step tutorial by schneems.

I have 2 controllers: Weddings and Wedding_steps. The user initially creates a Wedding and after the create action is redirected to the Wedding_steps controller (which uses Wicked) to update the wedding model with additional info.

The wedding_id is successfully detected in the first step weddingdetails, but after submitting that step, I get the following error:

ERROR

ActiveRecord::RecordNotFound in WeddingStepsController#update

Couldn't find Wedding without an ID: app/controllers/wedding_steps_controller.rb:11:in `update'

Parameters:

{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"JMd+8gf4rVqOSNMSFrKcD3WxK+X3zvYliSMWqTg0SkE=", "wedding"=>{"bridename"=>"", "groomname"=>"", "weddingdate"=>"", "weddingcity"=>"", "weddingstate"=>"", "url"=>""}, "commit"=>"Next", "id"=>"wedding_id=11"}

It is supposed to continue to the next step /wedding_steps/eventdetails?wedding_id=11 but instead gives the error and goes to /wedding_steps/wedding_id=11

Also of note is that without the Update action in place, the information successfully saves and redirects to the Wedding Show action.

Here is the relevant code:

wedding_steps_controller.rb

class WeddingStepsController < ApplicationController
include Wicked::Wizard
steps :weddingdetails, :eventdetails

def show
    @wedding = Wedding.find(params[:wedding_id])
    render_wizard
end

def update
    @wedding = Wedding.find(params[:wedding_id])
    @wedding.update_attributes(params[:wedding])
    render_wizard @wedding
end

end

weddings_controller.rb

def create
@wedding = current_user.weddings.new(params[:wedding])


respond_to do |format|
  if @wedding.save
    format.html { redirect_to wedding_steps_path(:id => "weddingdetails", :wedding_id => @wedding.id) }
    format.json { render json: @wedding, status: :created, location: @wedding }
  else
    format.html { render action: "new" }
    format.json { render json: @wedding.errors, status: :unprocessable_entity }
  end
end
end

STEP 1: wedding_steps/weddingdetails.html.erb

<%= simple_form_for(@wedding, :url => wizard_path(wedding_id: @wedding.id), :method => :put, html: { class: 'form-horizontal'}) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">


<div class="formrow center">
  <%= f.input :bridename, placeholder: "The Bride's Name", label: false %>
  <h2 class="inline">  &</h2>
  <%= f.input :groomname, placeholder: "The Groom's Name", label: false %>
</div>


<div class="formrow center">
  <%= f.text_field :weddingdate %> 
  <!-- OLD STYLE DATE FORMAT <%= f.input :weddingdate, label: "Wedding Date" %> -->
  <%= f.input :weddingcity, label: "City" %>
  <%= f.input :weddingstate, label: "State" %>
</div>


<div class="formrow center"> 
  <%= f.input :url, placeholder: "i.e. 'johnandkate' ", label: false %> 
</div>

</div>


<div class="form-actions center">
<%= f.button :submit, value: "Next" %>
</div>



<% end %>

<%= link_to 'skip', next_wizard_path(wedding_id: @wedding.id) %>

STEP 2: wedding_steps/eventdetails.html.erb

EVENT DETAILS STEP <!--PLACEHOLDER FOR NOW -->

Routes.rb

Jobshop::Application.routes.draw do    
    resources :pins
    resources :weddings
    resources :wedding_steps  

    get "users/show"

    root :to => 'pages#home'
    get 'about' => 'pages#about'

    devise_for :admin_users, ActiveAdmin::Devise.config
    ActiveAdmin.routes(self)

    resources :inviterequests


    devise_for :views
    ActiveAdmin.routes(self)

    devise_for :users
    ActiveAdmin.routes(self)

    match 'users/:id' => 'users#show'

    
Community
  • 1
  • 1
nishacodes
  • 197
  • 1
  • 9

2 Answers2

3

This line:

<%= simple_form_for(@wedding, :url => wizard_path, :method => :put, html: { class: 'form-horizontal'}) do |f| %>

Should be:

<%= simple_form_for(@wedding, :url => wizard_path(wedding_id: @wedding.id), :method => :put, html: { class: 'form-horizontal'}) do |f| %>

Note the wizard_path(wedding_id: @wedding.id) When you submit the form you should see parameters = {:wedding_id => some_number} in the logs.

Paste the output of the params for the update action if it doesn't work.

Edit:

You should have ":wedding_id" as part of the required url this will make it impossible to even generate a link to that controller unless it has a properly formatted url.

Replace this

resources :wedding_steps

with this

  scope "weddings/:wedding_id" do
    resources :wedding_steps
  end

So now a correct url would look like weddings/83/wedding_steps/weddingdetails. Likely one or more of your view helpers isn't including wedding_id properly and with this new constraint you will raise an error in the view, but this is a good thing since it will show you where the malformed link is.

Schneems
  • 14,918
  • 9
  • 57
  • 84
  • Here's what I'm seeing in the params after update action. ID seems to work, but it's not recognizing the next step? ------> `Parameters: {"utf8"=>"✓", "authenticity_token"=>"1MfI9JSd0RFoDhOYgxT1pxdouVShlwhI5dwJ4WG1NWQ=", "wedding"=>{"bridename"=>"Nisha", "groomname"=>"Arjun", "weddingdate"=>"", "weddingcity"=>"Houston", "weddingstate"=>"TX", "url"=>"arjunisha"}, "commit"=>"Next", "id"=>"wedding_id=83"} Completed 404 Not Found in 1ms ActiveRecord::RecordNotFound (Couldn't find Wedding without an ID): app/controllers/wedding_steps_controller.rb:11:in 'update'` – nishacodes Aug 12 '13 at 15:10
  • try this instead: :url => wizard_path(@wedding.id) remove the wedding: @wedding.id part, it should just return the number now – Adim Aug 13 '13 at 17:22
  • tried that as well. it still doesn't seem to fix the issue of the next step not loading. any other ideas? is there anything wrong with the code in the controller Update action? – nishacodes Aug 15 '13 at 14:44
  • @Adim wicked hijacks the id part of the param. – Schneems Aug 15 '13 at 18:18
  • @NishaDhingra to get this to work you need your params to look something like this `{"id" => "weddingdetails", "wedding_id" => 83, "wedding"=>{"bridename"=>"Nisha", # ... }` The form should look something like this `
    – Schneems Aug 15 '13 at 18:21
  • @Schneems, yep that's what i'm seeing on the first step of the wizard. When I hit next to go to the second step, it should be `
    – nishacodes Aug 15 '13 at 19:58
  • After you submit the form the first time, it should render hit the update action then render `eventdetails.html.erb`, what does that form helper look like? Can you update your question? Also your "skip" link needs the `wedding_id` too. – Schneems Aug 15 '13 at 23:26
  • Just updated the question w/more detailed error, routes file, and updated form. Sorry, I'm fairly new to rails and as far as i can tell there is no form helper. Can you glean anything new from these updates? – nishacodes Aug 16 '13 at 02:05
  • For your routes I recommend putting `":wedding_id"` into your scope. That way it will be impossible to even hit the controller without a properly formed URL. I updated my answer to include my suggestion of a scope. – Schneems Aug 16 '13 at 15:31
  • Thx, that's helpful. Now I see the following. Trying to fix first line of update? `Started PUT "/weddings/14/wedding_steps/wedding_id=14"` ... `Processing by WeddingStepsController#update as HTML Parameters: {"utf8"=>"✓",` ... `"commit"=>"Next", "wedding_id"=>"14", "id"=>"wedding_id=14"} Wedding Load (0.2ms) SELECT "weddings".* FROM "weddings" WHERE "weddings"."id" = ? LIMIT 1 [["id", "14"]] (0.1ms) begin transaction (0.1ms) commit transaction (0.1ms) begin transaction (0.0ms) commit transaction Redirected to http://localhost:3000/weddings/14/wedding_steps/wicked_finish` – nishacodes Aug 16 '13 at 21:56
  • That is weird, wicked should be doing the right thing automatically for you, but you can force it to do the right thing by changing your path to this `wizard_path(step, wedding_id: @wedding.id)` which should force the :id to be the same as `step` – Schneems Aug 17 '13 at 14:56
-1

I tried the solution provided by Schneems, however it is not running completely without errors. I implemented the following way.

Change

resources :wedding_steps

To

scope "weddings/:wedding_id" do
  resources :wedding_steps
end

The problem is parameters are displayed as forbidden based on the error that has been thrown as ActiveModel::ForbiddenAttributesError

To get rid off this,

Change

def update
  @wedding = Wedding.find(params[:wedding_id])
  @wedding.update_attributes(params[:wedding])
  render_wizard @wedding
end

To

def update
  @wedding = Wedding.find(params[:wedding_id])
  @wedding.update_attributes(wedding_params)
  render_wizard @wedding
end

private 
def wedding_params
  params.require(:wedding).permit(........your parameters here.................)
end
srbhattarai
  • 792
  • 7
  • 9