【问题标题】:Multi-step ActiveRecord's Model validation多步 ActiveRecord 的模型验证
【发布时间】:2016-11-13 20:16:10
【问题描述】:

考虑具有以下字段的用户模型:

  • 名字(必填)
  • 姓氏(必填)
  • 电子邮件(必填)
  • 密码(必填)
  • 电话(必填,大小:10 位)
  • 地址(必填)

还有一个包含以下步骤的多步骤注册表单:

  • 第一步,包含名字、姓氏和电子邮件字段
  • 第二步,输入密码、电话和地址。

您将如何创建一个解决方案来验证每个步骤中的输入?

标准的 ActiveRecord 方法不起作用,因为它一次验证所有字段。

我已经为这个问题创建了一个解决方案,但结果却是一个复杂的代码,所以我正在寻找替代方案。

【问题讨论】:

  • Lambda 基于step 属性的条件?当然,您可能会发现有一些复杂的控制器代码。 validates :first_name, presence: true, if: lambda { |user| user.step === 1 }。如果你找到了一个好的答案,Rails 社区很想知道 :)
  • 您是否需要一直拥有User 实例?您可以在此过程中构建一两个临时的非User 模型,然后在完成后将它们转换为真正的User。总体逻辑相同,但验证的条件性将通过模型分离来处理,而不是 User 中的一堆复杂性。

标签: ruby-on-rails validation activerecord


【解决方案1】:

就我个人而言,我会让模型管理它自己的验证,并将管理每个步骤的验证的逻辑移到那里。

现在,这可能不是最优雅的方式,但它很有效,不会使代码过于混乱。

为模型添加一个step 瞬态属性。

attr_accessor :step

将以下方法添加到模型中以检查是否在正确的步骤:

def on_step(step_number)
  step == step_number or step.nil?
end

step.nil? 的原因 - 这样做的好处是,如果您想在此模型上使用验证而不使用步骤,只需不要为您的模型上的步骤分配值,该方法将允许返回 true,从而使验证能够总是被执行。

将验证更改为仅在正确步骤时处理或在不使用步骤时绕过

validates :first_name, if: "on_step 1", presence: true
validates :last_name,  if: "on_step 1", presence:true
validates :email,      if: "on_step 1", presence:true

validates :password,   if: "on_step 2", presence:true
validates :phone,      if: "on_step 2", format:{ with: TEL_REGEX  }, allow_blank: false
validates :address,    if: "on_step 2", presence:true

当然不要忘记为模型设置当前步骤,例如通过将其硬编码在表单的隐藏字段中(如果为每个步骤呈现单独的表单)并更改您的参数以接收它。

【讨论】:

    猜你喜欢
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多