数据不会在向导的步骤之间保留

Data not persisted between steps in wizard

我已经按照 Nicolas Blanco's tutorial 为我的应用制作 "goal" 向导。

向导中有两个步骤。第一个由表单字段 "name"、"description" 和 "plan" 组成,第二个包含 "deadline",这是一个日期时间选择器,"reporting frequency" 和 "days missed tolerance" .

当我在第一步中单击继续时它似乎工作正常,但在第二步中单击完成时,对象 @goal_wizard 似乎不包含第一步中的参数。

我的goal.rb:

module Wizard
  module Goal
    STEPS = %w(step1 step2).freeze

    class Base
      include ActiveModel::Model
      attr_accessor :goal

      delegate *::Goal.attribute_names.map { |attr| [attr, "#{attr}="] }.flatten, to: :goal

      def initialize(goal_attributes)
        @goal = ::Goal.new(goal)
      end
    end

    class Step1 < Base
      validates :name, presence: true, length: { maximum: 50 }
      validates :description, presence: true, length: { maximum: 300 }
      validates :plan, presence: true, length: { maximum: 1000 }
    end

    class Step2 < Step1
      validates :reporting_frequency, presence: true, 
                                  numericality: { greater_than_or_equal_to: 0 } 
      validates :days_missed_tolerance, presence: true, 
                                    numericality: { greater_than_or_equal_to: 0}
      validates :deadline, presence: true
    end
  end
end

wizards_controller.rb:

class WizardsController < ApplicationController
  before_action :load_goal_wizard, except: :validate_step

  def validate_step
    current_step = params[:current_step]

    @goal_wizard = wizard_goal_for_step(current_step)
    @goal_wizard.goal.attributes = goal_wizard_params
    session[:goal_attributes] = @goal_wizard.goal.attributes


    if @goal_wizard.valid?
      next_step = wizard_goal_next_step(current_step)
      create and return unless next_step

      redirect_to action: next_step
    else
      render current_step
    end
  end

  def create
    # @user = current_user
    # @goal = @user.goals.new(@goal_wizard.goal)
    if @goal_wizard.goal.save
      session[:goal_attributes] = nil
      redirect_to root_path, notice: 'Goal succesfully created!'
    else
      redirect_to({ action: Wizard::Goal::STEPS.first }, alert: 'There were a problem creating the goal.')
    end
  end

  private

  def load_goal_wizard
    @goal_wizard = wizard_goal_for_step(action_name)
  end

  def wizard_goal_next_step(step)
    Wizard::Goal::STEPS[Wizard::Goal::STEPS.index(step) + 1]
  end

  def wizard_goal_for_step(step)
    raise InvalidStep unless step.in?(Wizard::Goal::STEPS)

    "Wizard::Goal::#{step.camelize}".constantize.new(session[:goal_attributes])
  end

  def goal_wizard_params
    params.require(:goal_wizard).permit(:name, :description, :plan, :deadline, :reporting_frequency, :days_missed_tolerance)
  end

  class InvalidStep < StandardError; end
end

step1.html.erb:

<ol class="breadcrumb">
  <li class='active'>Step 1</li>
  <li>Step 2</li>
</ol>

<%= form_for @goal_wizard, as: :goal_wizard, url: validate_step_wizard_path do |f| %>
  <%= render "error_messages" %>

  <%= hidden_field_tag :current_step, 'step1' %>
  <%= f.label :name %>
  <%= f.text_field :name, class: "form_control" %>
  
  <%= f.label :description %>
  <%= f.text_field :description, class: "form_control" %>
  
  <%= f.label :plan %>
  <%= f.text_field :plan, class: "form_control" %>

  <%= f.submit 'Continue', class: "btn btn-primary" %>
<% end %>

step2.html.erb:

<ol class="breadcrumb">
  <li><%= link_to "Step 1", step1_wizard_path %></li>
  <li class="active">Step 2</li>
</ol>

<%= form_for @goal_wizard, as: :goal_wizard, url: validate_step_wizard_path do |f| %>
  <%= render "error_messages" %>

  <%= hidden_field_tag :current_step, 'step2' %>
   <%= f.label :deadline %>
    <div class='input-group date' id='datetimepicker1'>
      <%= f.text_field :deadline, class: "form-control" %>
      <span class="input-group-addon">
        <span class="glyphicon glyphicon-calendar"></span>
      </span>
    </div>
        
  <%= f.label "How often do I want to report? (1 = every day)" %>
  <%= f.number_field :reporting_frequency, class: "form_control" %>
  
  <%= f.label "How many times can I miss my report?" %>
  <%= f.number_field :days_missed_tolerance, class: "form_control" %>
  
  
  <script type="text/javascript">
      $(function () {
          $('#datetimepicker1').datetimepicker({
             minDate:new Date()
          });
      });
  </script>

  <%= f.submit "Finish", class: "btn btn-primary" %>
<% end %>

在这里,您将 goal_attributes 传递给 initialize,但您从未使用过它们。

  def initialize(goal_attributes)
    @goal = ::Goal.new(goal)
  end

如果你看一下 Nicolas Blanco 的代码,他不会犯那个错误。