Ronan Lopes
Ronan Lopes

Reputation: 3398

Rails Simple Form - Add an error not related to attribute

I wanna do a validation that sums the values of nested fields so I make sure it's 100%. So, in my parent model, I would do the validation, and do a self.errors.add and add the error if the validation fails. The problem is, the errors.add as long as I know expects some attribute as argument, but it's not related to any attribute on my parent model, so I would like to display that message on the top of the form, for example. Any ideas of how I can do that? thank you!

UPDATE:

This is my parent model, where I wanna validate. The form has nested fields for :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

My create method, which it's the one I'm testing:

  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

--- Also, I debugged my object.errors.full_messages on the form, and the error is there. It's only not being displayed!

I guess that add errors to the base it's what I'm looking for. But now, it's not showing my message, but only that I have validation errors. My form code:

= 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

Upvotes: 1

Views: 2832

Answers (3)

Jeff Rossi Florencio
Jeff Rossi Florencio

Reputation: 51

i guess it should work for you

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

just

errors.add_to_base("")

Upvotes: 2

Gerardo S
Gerardo S

Reputation: 337

Updating the answer for this common question and if anybody finds it useful. You can use Errors#add(:base, msg) instead

I.E.

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

Upvotes: 0

C dot StrifeVII
C dot StrifeVII

Reputation: 1885

I think Jeff was on the right path, but I think the method you are supposed to use is model_instance.errors[:base].

I think you also might want to take into account the over all design of this feature (not that I have the full context of your app). if you have a validation of the parent model on its children model's it means that you will be saving erroneous children model to your data base only to then notify the user. Since it seems like this would be done with nested attribute you may want to consider doing this in the controller but there is an argument to be made about having too much logic in your controller.

Upvotes: 1

Related Questions