如何在ItemsController#show中复用多步表单第一步视图且避免代码重复?
我来给你几个简洁的思路,不用复制粘贴代码就能解决这个问题:
提取共享逻辑到Helper模块
把WizardsController里初始化@trade_wizard的核心代码(比如wizard_trade_for_step、读取session属性的逻辑)抽成一个独立的Helper模块,比如TradeWizardHelper。然后让ItemsController和WizardsController都include这个Helper。这样在ItemsController#show里,你只需要调用@trade_wizard = wizard_trade_for_step('step1')就能得到正确的实例,和WizardsController里的逻辑完全一致,没有冗余。封装Wizard实例化的类方法
在Wizard::Trade模块里新增一个类方法,把实例化的逻辑统一封装:def self.for_step(step, session_attrs = {}) raise InvalidStep unless step.in?(STEPS) "Wizard::Trade::#{step.camelize}".constantize.new(session_attrs) end这样不管是WizardsController还是ItemsController,都能直接用
Wizard::Trade.for_step('step1', session[:trade_attributes])来获取实例,避免重复写类型转换和步骤校验的代码。通过局部变量传递实例(可选优化)
如果你不想依赖控制器里的@trade_wizard实例变量,可以在渲染partial时直接传递局部变量:<%= render "/wizards/step1", locals: { trade_wizard: wizard_instance } %>记得把partial里的
@trade_wizard改成局部变量trade_wizard,这样耦合更低,以后在其他页面复用这个表单也更灵活。
内容的提问来源于stack exchange,提问作者calyxofheld

