向现有数据库模型添加验证

时间:2019-02-09 12:51:09

标签: ruby-on-rails ruby validation activerecord ruby-on-rails-5

我是一名初级开发人员(Ruby on Rails 5),目前正在现有模型上实施新的验​​证。仅当所涉及的属性不超过50个字时,验证才会通过。

  validates_length_of :reason, maximum: 50, too_long: 'Please reduce to 50 words or less',
                  tokenizer: ->(str) { str.split(/\s+/) }

很不幸,我们的数据库中已经有54条记录违反了此验证。因此,我正在寻找一种解决方案,以确保永远不会对这些现有记录进行验证。

到目前为止,我的研究产生了on: :create选项,这似乎很有希望,但是我希望获得一些经验丰富的反馈,以了解是否会遇到问题/错误。

此验证选项是否可以使我得到我想要的行为?

谢谢大家!

3 个答案:

答案 0 :(得分:1)

是的,您处在正确的轨道上,在处理现有数据时,您有一些选择。

您应该将验证添加到var newArray = yourArray.map( function( el ){ yourArray.options.map( function( eln ){ return eln.name; }) }); console.log (newArray); ,因为您不希望在单独的流程中更改其他不相关字段的人员(或工作)出错,因为原因无效且时间太长。

但是,如果仅添加on: create,则意味着某人可以创建少于10个单词的原因,然后将更新UI上的记录更新为60个单词,并且违反了验证。还考虑使用on: create添加相同的验证,这样可以防止更新破坏对创建操作施加的验证规则。

在这种情况下,您可以使用的另一种合理的解决方案是对现有记录进行数据迁移,对于每条违反验证的记录,您将单词缩减为49,最后添加if: :reason_changed?并保存。那会丢失信息,但是这意味着您可以始终100%地应用此验证。有时修复数据是编写更少代码的好选择。

无论您选择什么,都要确保进行测试以增强对代码正在执行您认为应该执行的操作的信心。

答案 1 :(得分:0)

新验证仅针对创建或更新操作运行。这意味着数据库中的现有记录将保持原样。换句话说,只要不更新它们,您就不会遇到任何问题。

这是您想要的吗?还是您希望在更新时允许大于50个单词的较早记录?如果确实需要,则可以创建一个新属性,称为例如legacy(旧有),对于任何现有记录,将其设置为true。您可以跳过对任何旧记录的验证。但我认为这有点不对。

答案 2 :(得分:0)

我会做这样的事情:

validates_length_of :reason, maximum: 50,
                             tokenizer: ->(str) { str.split(/\s+/) },
                             too_long: 'Please reduce to 50 words or less',
                             unless: -> { reason_was && reason_was.split(/\s+/).size > 50 }

这将执行验证,除非先前存在 reason 属性且该属性大于50。这意味着新记录的 reason 字数永远不会大于50,因为它们没有没有以前的 reason 值。如果以前的记录更大,则旧记录的 reason 字数只能大于50,否则,最大值为50。

这利用了ActiveModel::Dirty提供的方法生成的方法。