1

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
2
  • Could you post a code example of what you mean. It sounds like you are saying you have two models and you want to validate the sum of child models on the parent model that has a has many relationship with the child model. Is this right? Commented Dec 5, 2016 at 13:03
  • @CdotStrifeVII that's exactly it! I wanna update the post with some code, just one minute pls Commented Dec 5, 2016 at 13:04

3 Answers 3

2

i guess it should work for you

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

just

errors.add_to_base("")

Sign up to request clarification or add additional context in comments.

2 Comments

I think that method is deprecated I think you should use model_instance.errors[:base] instead
That's what I'm looking for, but, for some reason, it didn't showed anything (only the message of error validation, but not my message). I'm gonna update the post with the form code too
1

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.

5 Comments

that should do the trick. Since the validation on the parent fails, I believe it doesn't save the childs, does? Anyway, my problem now it's the message it's not being displayed on the form :/
Post your controller you have to add it to the flash hash then display that flash message in the html see this question stackoverflow.com/questions/7878662/…
Updated the question with my create method, which I'm testing now. Thanks!
I think you would have to send in the flash message as a param to the f.error_notification something like f.error_notification message: flash[:notice]
It displayed now, when I added = f.error :base to my form. It's not bootstraped, but from now I can make it work. Thanks!
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.