Rails 简单形式 - 添加与属性无关的错误

Rails Simple Form - Add an error not related to attribute

我想对嵌套字段的值求和进行验证,以确保它是 100%。因此,在我的父模型中,我会进行验证,并执行 self.errors.add 并在验证失败时添加错误。问题是,据我所知 errors.add 需要一些属性作为参数,但它与我父模型上的任何属性无关,所以我想在表单顶部显示该消息,例如.关于如何做到这一点的任何想法?谢谢!

更新:

这是我要验证的父模型。该表单具有 :arrendamento_contrato_unidades.

的嵌套字段
    class ArrendamentoContrato < ApplicationRecord

      has_many :arrendamento_contrato_unidades, dependent: :destroy

      validate :check_total_percentual_credito


  def check_total_percentual_credito
    if arrendamento_contrato_unidades.sum(&:percentual_credito).to_f != 100.0
      self.errors.add :base, "Tem que ser 100%"
    end
  end


    end

我正在测试的创建方法:

  def create


    @arrendamento_contrato = ArrendamentoContrato.new(arrendamento_contrato_params)

    respond_to do |format|
      if @arrendamento_contrato.save

        format.html { 
          flash[:notice] = flash_notice
          redirect_to action: "index"
        }
        format.json { render json: {status: 1, redirect: arrendamento_contratos_url} }
      else
        format.html { render :new }
        format.json { render json: {status: 0, errors: @arrendamento_contrato.errors, status: :unprocessable_entity} }
      end
    end
  end

--- 另外,我在表格上调试了我的object.errors.full_messages,错误就在那里。只是没有显示!

我想这会向基础添加错误,这正是我要找的。但是现在,它没有显示我的消息,而只是显示我有验证错误。我的表单代码:

= simple_form_for(@arrendamento_contrato, validate: true, html: { id:"dropzoneForm", class: "dropzone dz-clickable"}) do |f|
  = f.error_notification

  .form-inputs

    .row

      .col-md-6

        = f.input :numero

      .col-md-6

        = f.association :usina, input_html: {class: "chosen-select"}             

    .hr-line-dashed

    .row

      .col-md-6

        = f.association :esco_contrato, input_html: {class: "chosen-select"}

      .col-md-6

        = f.association :om_contrato, input_html: {class: "chosen-select"}


    .hr-line-dashed

    .row

      .col-md-4
        = f.input :data_inicio, as: :string, input_html: {"data-mask" => "date"} 

      .col-md-4
        = f.input :data_fim, as: :string, input_html: {"data-mask" => "date"} 

      .col-md-4
        = f.input :valor_mensal, as: :string, input_html: {"data-mask" => "decimal"}


    .hr-line-dashed        

    #arrendamento_contratos_unidades
      - if !@arrendamento_contrato.arrendamento_contrato_unidades || @arrendamento_contrato.arrendamento_contrato_unidades.empty?
        h3 = I18n.t('activerecord.models.unidade_consumidora.other')
        i
          'Aguardando ESCO...
      - else
        .row
          .col-md-6
            label class='control-label'
              = I18n.t('activerecord.models.unidade_consumidora.other')
          .col-md-6
            label class='control-label'
              = I18n.t('activerecord.attributes.arrendamento_contrato_unidade.percentual_credito')
        .hr-line-dashed
        .blockquote
          = f.simple_fields_for :arrendamento_contrato_unidades do |f|
            = render 'arrendamento_contrato_unidade_fields', f: f

    .hr-line-dashed

我想它应该适合你

https://apidock.com/rails/ActiveRecord/Errors/add_to_base

刚刚

errors.add_to_base("")

我认为 Jeff 的做法是正确的,但我认为您应该使用的方法是 model_instance.errors[:base]

我认为您可能还想考虑此功能的整体设计(并不是说我了解您应用的完整上下文)。如果您在子模型上对父模型进行了验证,则意味着您会将错误的子模型保存到数据库中,然后通知用户。由于这似乎是通过嵌套属性完成的,因此您可能想考虑在控制器中执行此操作,但对于控制器中的逻辑过多存在争议。

更新这个常见问题的答案,如果有人觉得它有用。您可以使用 Errors#add(:base, msg) 代替

I.E.

def validate_method
  errors.add(:base, 'Error message') if some_logic
  ...
end