Rails – skip validation in inherited classes.

Doing refactor in one of my applications I had to change behavior of single model. Since that was not total rewrite but just workflow change and I wanted to do A/B tests I needed both versions working.

Instead of writing completely new model I opted for using class inherited from old version. New class should have some additional behavior compared to previous version, so that approach made sense for me.

I ran on problem with validations. On old model validation was done in single step – object was in state ‘not ready’ and until it was completed part of validations was not run. When it was in ‘ready state’ then validations were enabled. Problem was that in new behavior, object building should be done in two steps. Normally that is not problem, since part of validations can be run from one stage and part can be run when other condition is present.

Since I have chosen inheritance, old, one-step validation was present in child model. I had to remove this one-step validation and add new. So there is how it can be done (Rails 4.2):

First, You need to know what kind of validator it is. In my case it was attribute presence validator for :address. Such validator is ActiveRecord::Validations::PresenceValidator. In case You don’t know exactly where to find it, You can always check all validators in given object. Just create object instance in console, and pretty print object._validate_callbacks. Then find “Your” validator and it’s attributes. Having that info (class and attributes) add to Your model:

old_validator = _validate_callbacks.find do |c|
    c.filter.is_a?(ActiveRecord::Validations::PresenceValidator) &&
        c.filter.instance_variable_get(:@attributes) == [:address]
  end.filter
  skip_callback :validate, old_validator

Replace validator class and attribute name in check to matching Your case.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.