validate :something, except: :create

Greeting,

Want to gather your :+1: and :-1: on an idea I had, before spending time working on a PR.

The idea is simple
The same way that ActiveModel::Validations::ClassMethods#validates accepts the option on to specify the contexts where this validation is active, I’m thinking to add the option except to exclude contexts where the validation is active.

Use case
Publication has many Page, AttachmentFile, Image, Comments etc…

All those model have their own set of validation that execute on create and on update. Few of them are quite expensive (such as triggering database access to verify uniqueness)

Publication can be published. Before publishing we run a specific set of validations with on: :publishing
options. Those validation are not needed for the model to exist on the database, but needed for the publishing operation. But, we don’t want to
run again the expensive original sets of validation, we assume they are
already valid anyhow because the record exists in the database.

How to do
Currently, this works perfectly:

  with_options unless: Proc.new { |record| record.validation_context == :publishing } do |record|
record.validates_presence_of :things
record.validates_uniqueness_of :fields, scope: :publication_id
end
with_options on: :publishing do |record|
record.validates_presence_of :pages
end
 

Suggestion
But it is not very intuitive and require to dive a bit into the source code to find about validation_context before being able to implement it.

So I would suggest to write:

  with_options except: :publishing do |record|
...
end
 

Thoughts?

Up
Any thoughts?

I wish something like that on ActiveRecord yesterday, so, definitely :+1:.

I’d love to see this feature added to rails core, and thanks Benjamin for posting this workaround for now :smiley:

Submitted
https://github.com/rails/rails/pull/22369