【问题标题】:How can I skip a specific validation when importing data?导入数据时如何跳过特定验证?
【发布时间】:2012-12-03 15:43:37
【问题描述】:

如何在导入数据时跳过特定的模型验证?

例如,假设我有这个模型:

class Account
  validates :street_address, presence: true
end

通常,我不希望没有地址的帐户被保存,但我还要转换旧系统中的大量数据,而那里的许多帐户没有地址。

我的目标是我可以将旧帐户添加到新数据库中,但是将来在编辑这些帐户时,必须添加街道地址。

澄清

正如我所说,我想跳过特定验证;其他人应该仍然运行。例如,根本不应该将没有帐号的帐户加载到新系统中。

【问题讨论】:

    标签: ruby-on-rails ruby activerecord


    【解决方案1】:

    这应该可行:

    class Account
      attr_accessor :importing
      validates :street_address, presence: true, 
        unless: Proc.new { |account| account.importing }
    end
    
    old_system_accounts.each do |account|
      # In the conversion script...
      new_account = Account.new
      new_account.importing = true   # So it knows to ignore that validation
      # ... load data from old system
      new_account.save!
    end
    

    【讨论】:

    • 在数据库中有一个布尔值是一个好方法。您可能会考虑编辑标题,因为这实际上是关于数据之前和之后的状态,而不是关于条件验证。
    • @TomHarrisonJr - 实际上,在我的示例中,布尔值不会被持久化;这只是一个attr_accessor。这样它就会进入数据库,但一旦进入数据库,它就不会被特殊处理,并且需要任何更新它的人提供街道地址。
    【解决方案2】:

    如果您只打算进行一次转换(即,在导入旧数据后,您无需再次执行此操作),您可以在保存导入的记录时直接skip validations,而不是修改您的应用程序来支持它。

    new_account.save validate: false
    

    【讨论】:

    • 我只想跳过特定验证,而不是全部验证。
    • 我明白了。那么我认为你的方式可能是最好的选择。
    【解决方案3】:

    注意

    account.update_attribute(:street_address, new_address)
    

    也会跳过验证。 #update_attributes(注意“s”)运行验证,而 update_attribute(单数)不运行。

    【讨论】:

    • update_attribute 立即触发保存。我宁愿设置我所有的属性并保存一次。
    猜你喜欢
    • 2011-08-29
    • 2021-09-16
    • 2016-12-04
    • 1970-01-01
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多