rails :嵌套表单中的验证与 reject_if

rails : validation vs reject_if in nested forms

我有一个模型 A,它接受模型 B 的嵌套属性。模型 B 条目的数量以及是否需要条目取决于数据库中的第 3 个 table。我使用 form_for 为模型 B 条目生成一个带有 fields_for 的表单。这就是验证需要如何工作:

  1. 如果对应的 :required 字段为假,模型 B 的条目允许为空,但不应保存,即该条目不应引发验证错误,但应被 :reject_if.
  2. :required字段为真的条目不允许为空。 :reject_if 不应拒绝这些条目,但在将其保存到数据库时会引发验证错误。

    class modelA < ApplicationRecord
      has_many :modelBs, dependent: :destroy
    
      accepts_nested_attributes_for :modelBs, reject_if: :not_required_and_blank?
    
      def not_required_and_blank?
         # return true if modelB.entry is blank && modelB.required_entry? is false
      end
    end
    
    class modelB < ApplicationRecord
      belongs_to :modelA
      validates :modelB_entry, presence: true, if: :required_entry?
    
      def required_entry?
        ModelC.find(:id).required
      end
    end
    

我应该这样做吗

  1. accepts_nested_attributes_for:reject_if 选项中(在模型 A class 中)和 validates_presence_of modelB_entry 方法中(在模型 B class 中)或
  2. :reject_if
  3. 中的所有内容
  4. :validates_presence_of 中的所有内容?

哪个先执行:reject_if or vaildation?

reject_ifvalidations 有不同的用途。

假设您有一个嵌套模型 modelB,其中包含两个字段 nametitle,其中 name 作为必填字段。

使用reject_if

在控制器 #new 操作中,您决定自己构建第一个嵌套对象,以便为用户提供更好的 UI 体验,以便他可以轻松地看到他还可以添加到表单中的内容。或者用户自己点击“+ 添加更多”按钮。但随后决定将 modelB 留空,不在其中输入任何信息。现在,如果您不使用 reject_if 但您进行了验证,用户将收到错误消息,指出字段为空,并且他将无法提交表单,除非他单击 remove按钮。

因此,在这种情况下,您将检查 reject_if 中的所有字段是否为空,如果是这样我们可以忽略该记录,否则让模型完成它的工作。

此外,请记住 reject_if 不能保证数据完整性。因为任何典型的 RoR 应用程序都有多个入口点。

在我看来,你应该选择第一个选项。同时使用 reject_if 和验证