Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to add custom errors when import fails #137

Open
davideluque opened this issue Dec 28, 2022 · 4 comments
Open

How to add custom errors when import fails #137

davideluque opened this issue Dec 28, 2022 · 4 comments

Comments

@davideluque
Copy link

davideluque commented Dec 28, 2022

I want to show custom errors when the association is not present or unique.

Rails uniqueness validation adds these errors: MyAssociation has been taken / MyAssociation must exist

When I try

validates :my_association, uniqueness: {message: "This is my custom message"}

It shows

My Association has been taken. My Association This is my custom message

I am also trying to add other errors not related to validations but to finding a model related to this.

My code:

class Report < ApplicationRecord
  validates :my_association, uniqueness: true

  def after_import_error(record)
    if CustomModel.find(record[:custom_attribute])
      self.errors.add(:base, "Custom attribute does not exist")  # This does not work! The error is not added
  end
end

Probably a Rails-related question but I would love it if you could help in combination with Rails Admin.

Thanks!

@davideluque
Copy link
Author

It would be nice to modify the entire error string, is that possible?

@davideluque
Copy link
Author

I also tried to add the error in the before_import_save

  def before_import_save(record)
    custom_model = CustomModel.find(record[:custom_attribute])

   errors.add(:base, "Custom message") unless custom_model
  end

@monkbroc
Copy link
Collaborator

Hi. I don't have a ready made answer for you here. If you are willing to dig into the code of the gem and the rails admin gem to find out where error messages are constructed, and how to add a hook for a custom error message, please open a PR. Make sure to add a paragraph in the README on how to set up custom error messages.

@newfylox
Copy link

2 years later, I was trying to achieve the same result and I think I know why it's not working.

When calling save method on a model instance, behind the scenes it calls valid? to check validation and to add errors. But BEFORE calling those validations, it clears previous error messages.

So when adding an error in a callback like this

def before_import_save(record)
  # code
  errors.add(:base, "Custom message")
  # code
end

it quits the callback before_import_save and then calls save on this object right after, hence clearing previous errors, right here

perform_model_callback(object, :before_import_save, record)
if object.save
report_success(object, action)
perform_model_callback(object, :after_import_save, record)
else
report_error(object, action, object.errors.full_messages.join(", "))
perform_model_callback(object, :after_import_error, record)
end

One solution that I found is to create a dumb attribute on the model to set the error message, and then validate that this attribute is empty. And if not, set this error message on whatever attribute you want. Something like this

# add this dumb attribute to your model
attr_accessor :import_error_message

# add a new validation to your model
validate :no_import_error

# somewhere in your before_import_save callback
def before_import_save(record)
  # code throwing error
rescue => error
  self.import_error_message = error.message # set the dumb attribute to use it later in validations
end

# define this new validation
def no_import_error
  if import_error_message # check if there is an error message
    errors.add(:base, import_error_message) # add this error on the attribute of your choice, here :base
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants