代码之家  ›  专栏  ›  技术社区  ›  BvuRVKyUVlViVIc7

向导样式表单的验证组

  •  1
  • BvuRVKyUVlViVIc7  · 技术社区  · 16 年前

    有人能给我解释一下,如何使用验证进行向导样式的表单吗?

    F.E.

    我有一个预约模型,应该包括以下数据: 姓名,开始时间,结束时间,地址,城市。

    现在,我想对每个数据组执行3个操作:

    1. 名称
    2. 开始和结束日期
    3. 地址字段

    它们中的每一个都应该是可访问的 (因此,我认为aasm不是一个选项->model.wizard_step=3,为此步骤生成正确的视图还不够)。

    每一个都应该有验证

    1. 名称不应为零
    2. 开始日期不能晚于结束日期
    3. 地址字段不能为空

    但是,如何在单个步骤之间保存这个对象,以及如何在这个验证模式/组中构建……?

    海尔普 谢谢=)

    4 回复  |  直到 15 年前
        1
  •  3
  •   Juice10    15 年前

    您可以使用分组验证gem进行以下操作: https://github.com/adzap/grouped_validations

        2
  •  1
  •   Tor Erik Linnerud    16 年前

    在表单中组合隐藏字段:

    f.hidden_field :wizard_stage, :value => '<current action>'
    

    像这样的东西

    class Appointment < ActiveRecord::base
    
       attr_accessor :wizard_stage
    
       validates_presence_of :name, :if => lambda{|a| a.wizard_stage == 'name'}
       validates_presence_of [:start, :end], :if => lambda{|a| a.wizard_stage = 'dates'}
    end
    
        3
  •  0
  •   Stephen Touset    16 年前

    你必须基本上“自己动手”。使用标准Rails/ActiveRecord功能最接近的方法是执行以下操作:

    class WizardController < ApplicationController
      def wizard_1
        foo = Foo.new params[:foo]
        foo.valid?
    
        if %{name}.any? {|att| foo.errors.on(att) }
          # failed pseudo-validation
        else
          render :wizard_2
        end
      end
    
      def wizard_2
        foo = Foo.new params[:foo]
        foo.valid?
    
        if %{name startdate enddate}.any? {|att| foo.errors.on(att) }
          # failed pseudo-validation
        else
          render :wizard_3
        end
      end
    
      def wizard_3
        # standard rails Controller#create
      end
    end
    

    你必须把每一步的变量传递到下一步的隐藏字段中。您可能还想考虑只在一个阶段完成这项工作,而不是在三个阶段完成这项工作。

        4
  •  0
  •   Omar Qureshi    16 年前

    你就不能用:如果?

    例如

    validates_presence_of :name
    validates_presence_of :address_fields, :if => Proc.new {|p| p.startdate && p.enddate}
    
    def validate
      unless name.blank?
        errors.add(:startdate) if startdate > enddate 
      end
    end