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
我想对嵌套字段的值求和进行验证,以确保它是 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