我正在努力学习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
其中:id_string
和:pin_number
都是表单字段,并且会比较为value1
和value2
有办法做到这一点吗?
非常感谢提前!
注意:上面的值比较确实可以通过一点点javascript在前端解决。我要求服务器端解决方案的原因是我最终打算将这两个值与数据库中的一组条目进行比较。上面的例子只是为了简化我的问题。
答案 0 :(得分:1)
您可以考虑使用JS方法验证值onClick
或者您认为可以给予适当控制的其他操作,而不是在Rails端进行验证。
onClick
所需要的只是一种从每个唯一命名的表单字段中获取值的简单方法,然后只比较每个字段的val()
和允许/拒绝提交。
如果您需要将表单字段与存储在数据库中的值进行比较,您可以使用<input type="hidden>
并在加载页面时存储该值,以便仍然可以按照描述的相同方式进行比较上方。
答案 1 :(得分:1)
您应该可以在@attributes
方法中访问使用validate_each
列出的属性,因为您可以从初始化代码here推断出
因此,您可以使用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
方法将运行两次,因为它应该为验证定义中列出的每个字段运行。这可能导致错误被插入两次或其他问题。我正在研究是否每次运行验证时都会创建验证器实例,如果是这样的话,你可以通过设置一个标志来避免这种双重验证,比如说{{1}}然后如果第二次该标志为真则返回。由于下次需要验证任何内容时都会创建验证器的新实例,因此该标志不会影响其他任何内容。