-1

I defined a custom EachValidator to see if an attribute has leading or trailing whitespace. I know you can add it to the model like so:

validates :name, whitespace: true

But in the controller I want to call just run just the whitespace validator for some form feedback.

I can run it like this:

Validators::WhitespaceValidator.new(attributes: :name).validate_each(obj, :name, obj.name)

Is there a shorter way to call the specific validator? Like you can do user.valid? but that runs all of the validations. I only want the whitespace validator on the name attribute.

Ashbury
  • 2,160
  • 3
  • 27
  • 52
  • 1
    I would say that you're violating encapsulation by doing it this way. You want to do something in your controller, unrelated to the model, but you want to use model-specific code to do it. It's not a good practice, it makes your code brittle, it violates encapsulation, it's confusing for others that might read it in the future, etc. – anothermh Jan 26 '23 at 06:27

2 Answers2

1

Since you did not come here to be told that your idea is bad and people will hate it: here is an idea that you can play with: :on

https://guides.rubyonrails.org/active_record_validations.html#on

validates :name, whitespace: true, on: :preview

and then in the controller:

def something
  @model.valid?(:preview)
end

If you want to run the validation also on createand update you can specify something like

on: [:create,:update,:preview]

(Thanks engineersmnky)

Also: I don't think that giving early feedback to users, before they actually save the record is a bad idea if properly implemented.

Pascal
  • 8,464
  • 1
  • 20
  • 31
  • *"I guess you'd need to define ithe whitespace part twice, once for :preview and once for normal validation/save."* You could just pass the other contexts to `on:` e.g. `on: [:create,:update,:preview]` – engineersmnky Jan 26 '23 at 14:31
  • true, even better. – Pascal Jan 26 '23 at 18:25
0

This feels like trying to solve a problem (leading/trailing whitespace) by creating a new problem (rejecting the object as invalid), and I agree with the comment about this being a brittle strategy. If the problem you want to solve here is whitespace, then solve that problem for the specific attributes where it matters before saving the object; check out Rails before_validation strip whitespace best practices

Allison
  • 1,925
  • 1
  • 18
  • 25
  • I'm using it to return a validation error to frontend to let the user know they added whitespace. – Ashbury Jan 26 '23 at 07:06
  • 1
    @Ashbury Strongly advise against exerting development effort on form feedback about untrimmed whitespace as it forces users into a confusing experience they will HATE. Unless you're doing some sort of nonsensical school project that explicitly asks you to do it that way, you should just strip the attribute's whitespace before saving it in your model. If you want something you can use to strip whitespace across models, define a Concern you can reuse. – Allison Jan 26 '23 at 07:56
  • Not sure this "answers" the question but I can agree with the sentiment. There is no need to yell at a user for something that is easily corrected with sanitization. – engineersmnky Jan 26 '23 at 18:38
  • Yeah I appreciate the answer and you made me rethink -why- I was choosing to go down this path. The answer is what I'm working with involves encryption, so I need to inform users when characters are slightly off (name, input, output, radix, passthrough, etc). If they put a space in the client lib, and copy it to the UI, then the backend strips it, there will be a mismatch that will be hard to find. The warning helps catch that error. – Ashbury Jan 27 '23 at 01:10