cal*_*eld 5 ruby ruby-on-rails wizard formwizard
我想渲染多步形式的第一步@trade_wizard(它有自己的控制器WizardsController)作为部分内部ItemsController#show,但我不知道如何构建它而不将代码从一个控制器加倍到另一个控制器.
我正在渲染Item的显示页面中的第一步:
<%= render "/wizards/step1" %>
Run Code Online (Sandbox Code Playgroud)
@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
Run Code Online (Sandbox Code Playgroud)
然后我的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, :trade_recipient_id, :wanted_item_id, :collateral_item_id, :shares, :agreement)
end
class InvalidStep < StandardError; end
end
Run Code Online (Sandbox Code Playgroud)
在我的路线我有
resource :wizard do
get :step1
get :step2
get :step3
post :validate_step
end
Run Code Online (Sandbox Code Playgroud)
我通过此设置获得的错误是First argument in form cannot contain nil or be empty.我知道为什么会发生这种情况 - 我需要@trade_wizard在ItemsController#show中定义,我还没有这样做,因为这只会导致我从WizardsController复制代码.我不需要任何人为我做我的工作,我只需要一个指针,指出我如何能够解决这个问题.
| 归档时间: |
|
| 查看次数: |
547 次 |
| 最近记录: |