Errors inside custom setters

Hi there,

I’ve got a custom setter in a model that add errors in the case that the given value is invalid. In the case that it is invalid, I’ve had a lot of difficulty getting the model to validate false. It looks like in active model we call errors.clear before run_validations!. This makes sense to me, as you might save a record, validate false, update the values, and then not want to keep the old errors.

Is there any way around this? Best I could come up with is to set an attr_accessor flag to :invalid if the setter was invalid and then validate absence of that attr_accessor.

Would there be interest in a PR that extended errors to have some persistent values through the validation stack? As in, you set a sticky error that doesn’t get removed when you call valid? Or something? Sorry, that part of this is not super thought-out.

Hi,

is there any reason why you could not move the validation to a proper validation “callback” so that it’d work like any other validation does? I mean, if you know the value is wrong in the moment you’re setting, you could allow it to be set and validate the same afterwards, but there’s probably something I’m not seeing - maybe you can share some code to help out?

Anyway, if you really need to do that I’d recommend doing as you said, detect on the setter but only add the error upon validation.

Hi Carlos,

It’s not actually a persisted attribute. I effectively have

class Thingy

def xml=(string)

xml_doc = Nokogiri::XML(string) { |config| config.noblanks.strict }

more code here

rescue Nokogiri::XML::SyntaxError => error

self.errors.add(:xml, error.message)

end

def xml

some code here, effectively to_xml

end

end

I see. Well, that doesn’t mean you could not store “something” that represents your xml attribute - or you could have an xml_error that stores the error message in this case, and adds it to the errors instance when validating (which is probably very similar or exactly what you’re doing already).

I’m not sure having “sticky” errors would be super helpful. For example, you sure you want them to be “sticky” if you set xml twice on the same instance? Would you have to clear that error yourself in this case, because you’re handing it on your own? It seems a lot to handle.

Anyway, those are my thoughts, maybe someone else has a new opinion on this :).

Hope that helps.

Makes sense. Thanks for the help! I’ll stick with the attribute that adds the validation during the callback stack. Hopefully this is a rare enough case that I won’t need to do this again.