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