Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 将多步骤表单向导的第一步呈现为另一个控制器中的一部分';让我们行动起来_Ruby On Rails_Ruby_Wizard_Formwizard - Fatal编程技术网

Ruby on rails 将多步骤表单向导的第一步呈现为另一个控制器中的一部分';让我们行动起来

Ruby on rails 将多步骤表单向导的第一步呈现为另一个控制器中的一部分';让我们行动起来,ruby-on-rails,ruby,wizard,formwizard,Ruby On Rails,Ruby,Wizard,Formwizard,我想将@trade\u wizard(它有自己的控制器,wizardscocontroller)的多步骤表单的第一步呈现为ItemsController#show)中的一部分,但我不知道如何在不将代码从一个控制器加倍到另一个控制器的情况下构建它 我正在项目的显示页面中呈现第一步: <%= render "/wizards/step1" %> 我在这个设置中遇到的错误是表单中的第一个参数不能包含nil或为空。我知道为什么会发生这种情况-我需要在ItemsController#show

我想将
@trade\u wizard
(它有自己的控制器,
wizardscocontroller
)的多步骤表单的第一步呈现为
ItemsController#show
)中的一部分,但我不知道如何在不将代码从一个控制器加倍到另一个控制器的情况下构建它

我正在项目的显示页面中呈现第一步:

<%= render "/wizards/step1" %>

我在这个设置中遇到的错误是
表单中的第一个参数不能包含nil或为空
。我知道为什么会发生这种情况-我需要在ItemsController#show中定义
@trade_wizard
,我还没有这样做,因为这只会导致我从WizardsController复制代码。我不需要任何人帮我做我的工作,我只需要一个指针,告诉我如何解决这个问题。

控制器是独立设计的,它们不能相互依赖。这不同于视图,也不同于您现在所做的可以通过部分重用和组合的视图

如果您需要重用控制器中的行为(这与一个控制器依赖于另一个控制器不同),您可以使用继承,或者按照Rails的方式

在本例中,我将创建一个关注点,在包含
向导/step1
部分视图的任何控制器中设置
@trade\u向导
变量。

如中所述,我将使用ajax隐藏和显示步骤,并结合嵌套表单

您可以创建一个
向导
模型,该模型包含许多步骤,并接受
步骤
作为
嵌套属性
。您可以在

这是你的表格

<%= form_for @wizard, class: 'hidden' do |f| %>
  Addresses:
  <ul>
    <%= f.fields_for :steps do |step| %>
       // include your fields
    <% end %>
  </ul>
<% end %>

我本来会写更多的,但如果不同的控制器需要共享代码,我需要去

,然后把它放在控制器助手中。或者制作一个基本控制器并扩展它。您的分部是否实际生成自己的请求?我的意思是,这是一种AJAX类型的情况,在这种情况下,您处理请求并只更新页面的一部分?如果没有,则部分的控制器听起来很奇怪。每个步骤都会发出一个
POST
请求,以
validate\u step\u wizard\u path
,然后重定向到下一步,因此是的,部分将生成自己的请求。
class WizardsController < ApplicationController
  before_action :load_trade_wizard, except: %i(validate_step)

  def validate_step
    current_step = params[:current_step]

    @trade_wizard = wizard_trade_for_step(current_step)
    @trade_wizard.trade.attributes = trade_wizard_params
    session[:trade_attributes] = @trade_wizard.trade.attributes

    if @trade_wizard.valid?
      next_step = wizard_trade_next_step(current_step)
      create and return unless next_step

      redirect_to action: next_step
    else
      render current_step
    end
  end

  def create
    if @trade_wizard.trade.save
      session[:trade_attributes] = nil
      redirect_to root_path, notice: 'Trade succesfully created!'
    else
      redirect_to({ action: Wizard::Trade::STEPS.first }, alert: 'There were a problem when creating the trade.')
    end
  end

  private

  def load_trade_wizard
    @trade_wizard = wizard_trade_for_step(action_name)
  end

  def wizard_trade_next_step(step)
    Wizard::Trade::STEPS[Wizard::Trade::STEPS.index(step) + 1]
  end

  def wizard_trade_for_step(step)
    raise InvalidStep unless step.in?(Wizard::Trade::STEPS)

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

  def trade_wizard_params
    params.require(:trade_wizard).permit(:trade_requester_id, :trade_recipient_id, :wanted_item_id, :collateral_item_id, :shares, :agreement)
  end

  class InvalidStep < StandardError; end
end
resource :wizard do
    get :step1
    get :step2
    get :step3
    post :validate_step
end
class Wizard < ActiveRecord:Base
   has_many :steps
   accepts_nested_attributes_for :steps
end
class Step < ActiveRecord:Base
   belongs_to :wizard
end
<%= form_for @wizard, class: 'hidden' do |f| %>
  Addresses:
  <ul>
    <%= f.fields_for :steps do |step| %>
       // include your fields
    <% end %>
  </ul>
<% end %>
# app/controllers/wizards_controller.rb
# ......
def create
  @wizard = Wizard.new(params[:wizard])

  respond_to do |format|
    // you can set conditions and perform different AJAX responses based on the request you received. 
    format.js
    format.html { render action: "new" }
  end
end