-1

我正在学习 Rails 中的自定义验证,并试图将其应用于比较两个表单字段。到目前为止,我可以轻松地将一个值传递给我存储的自定义验证器,app/validation/pin_validator.rb并且它工作正常。但我真的很想设置类似下面的东西,它会接受表单中的两条数据:

class PinValidator < ActiveModel::EachValidator
  def validate_each (record, attribute, value)
    if value1 > value2
      record.errors[attribute] << (options[:message] || "validator working")
    end
  end
end

并从模型中调用它,如下所示:

validates :pin_number, :id_string, pin: true

Where:id_string:pin_number都是表单字段,并且将被比较为value1andvalue2

有没有办法做到这一点?

提前谢谢了!

注意:上面的值比较确实可以在前端用一点javascript来解决。我要求服务器端解决方案的原因是我最终打算将这两个值与数据库中的一组条目进行比较。上面的例子只是为了把我的问题提炼成简单的东西。

4

2 回答 2

1

与其在 Rails 端进行验证,不如考虑使用 JS 方法来验证值onClick或执行您认为可以适当控制的其他操作。

您只需要onClick一个简单的方法来从每个唯一命名的表单字段中获取值,然后只需比较val()每个字段的 s 并允许/拒绝提交。

如果您需要将表单字段与存储在数据库中的值进行比较,您可以<input type="hidden>在页面加载时使用并存储该值,以便仍然可以以上述相同方式进行比较。

于 2014-12-09T21:49:04.080 回答
1

您应该能够访问方法@attributes内列出的属性,正如您可以从这里validate_each的初始化代码中推断的那样

因此,在您的情况下,您可以record使用值来访问属性,@attributes该数组中的属性名称是在验证定义中使用的属性名称[:pin_number, :id_string]。您可以像访问它们一样

def validate_each(record, attribute, value)
   value1 = record[@attributes[0]] # :pin_number
   value2 = record[@attributes[1]] # :id_string
   # the rest of the logic here
end

我意识到该validate_each方法将运行两次,因为它应该为验证定义中列出的每个字段运行。这可能会导致错误被插入两次或其他问题。我正在研究是否在每次运行验证时都创建验证器实例,如果是这样,您可以通过设置一个标志来避免这种双重验证,比如@already_run第二次返回该标志是否为真。由于下次需要验证任何内容时将创建验证器的新实例,因此该标志不会影响其他任何内容。

于 2014-12-09T22:24:03.970 回答