ruby-on-rails – 将多步骤表单向导的第一步渲染为另一个控制器
发布时间:2020-12-17 03:10:50 所属栏目:百科 来源:网络整理
导读:我想为@trade_wizard(它有自己的控制器,WizardsController)渲染多步形式的第一步作为部分内部ItemsController#show,但我不知道如何构建它而不将代码从一个控制器加倍到其他. 我正在渲染Item的显示页面中的第一步: %= render "/wizards/step1" % @trade_wiza
我想为@trade_wizard(它有自己的控制器,WizardsController)渲染多步形式的第一步作为部分内部ItemsController#show,但我不知道如何构建它而不将代码从一个控制器加倍到其他.
我正在渲染Item的显示页面中的第一步: <%= render "/wizards/step1" %> @trade_wizard在实例化@trade的特殊模型中处理,然后从每个步骤连续继承验证: module Wizard module Trade STEPS = %w(step1 step2 step3).freeze class Base include ActiveModel::Model attr_accessor :trade delegate *::Trade.attribute_names.map { |attr| [attr,"#{attr}="] }.flatten,to: :trade def initialize(trade_attributes) @trade = ::Trade.new(trade_attributes) end end class Step1 < Base validates :trade_requester_id,:trade_recipient_id,:wanted_item_id,presence: true validates :shares,numericality: { only_integer: true,greater_than_or_equal_to: 0,less_than_or_equal_to: :max_shares } def max_shares @trade.wanted_item.shares end end class Step2 < Step1 validates :collateral_item_id,presence: true end class Step3 < Step2 validates :agreement,presence: true end end end 然后我的WizardsController在每一步上运行验证并保存对象: 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,:collateral_item_id,:shares,:agreement) end class InvalidStep < StandardError; end end 在我的路线我有 resource :wizard do get :step1 get :step2 get :step3 post :validate_step end 我通过此设置获得的错误是表单中的第一个参数不能包含nil或为空.我知道为什么会发生这种情况 – 我需要在ItemsController#show中定义@trade_wizard,我还没有这样做,因为这只会导致我从WizardsController复制代码.我不需要任何人为我做我的工作,我只需要一个指针,指出我如何能够解决这个问题. 解决方法
控制器设计为独立的,它们不能相互依赖.这与视图不同,可能正如您所做的那样,可以通过部分重用和组合.
如果您需要重用控制器中的行为(与一个控制器不同,取决于另一个控制器),您可以使用继承,或遵循Rails方式,concerns. 在这种情况下,我会在包含向导??/ step1partial视图的任何控制器中设置@trade_wizard变量. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |