说,如果我们有
class SomeData < ActiveRecord::Base
validates :foo, inclusion: 33..99
现在,我们说,我们将范围缩小到66..99
,但是数据库中有许多值仍在33到65之间,可以将上面的代码更改为
class SomeData < ActiveRecord::Base
validates :foo, inclusion: 66..99
立即?如果只是将数据读入系统是否有问题?(甚至在Rails的早期版本中,例如3.2?)
更改验证实际上并不会以任何方式直接影响数据库中的现有数据。只有#valid?
在模型上调用时,才运行验证。
调用时隐式发生:
.create
和 .create!
#save
和 #save!
#update
和 #update!
并且它导致这些方法无法使用,因此要么发生回滚,要么首先不触发任何数据库查询。
我们可以立即更改验证吗?
是。仅当您尝试更新现有记录时,验证才会真正生效。在这种情况下,以前有效的记录现在可能无效。除非将值更新为新的允许范围,否则这将不允许更新。
如果要让用户仍然根据新规则使用无效数据来更新现有记录,则有一些服务器技巧。
if:
和unless:
选项class SomeData < ActiveRecord::Base
validates :foo, inclusion: 33..99, if: :legacy_record?
validates :foo, inclusion: 66..99, unless: :legacy_record?
end
有几种方法可以实现:legacy_record?
数据库中的布尔标志。请注意,这些不应与ruby关键字混淆。它们只是哈希选项。
class SomeData < ActiveRecord::Base
validate :my_validation_method
def my_validation_method
rng = legacy_record? ? 33..99 : 66..99
errors.add(:foo, "out of range") unless rng.cover?(foo)
end
end
class Thing < ActiveRecord::Base
validates :foo, inclusion: 66..99
end
class LegacyThing < ActiveRecord::Base
self.table_name = "things"
validates :foo, inclusion: 33..99
end
在此示例中,您将添加things.type
varchar列,并使用来更新现有行things.type = "LegacyThing"
。这并不是真正的STI,它只是使用ActiveRecord内置的机制。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句