[Rails] on :: Action Conditionally set callback cannot be avoided by using skip_callback and set_callback

When I tried to avoid the callback temporarily using skip_callback and set_callback, set_callback did not work. Record the situation and workaround at that time.

Thing you want to do

I want to temporarily skip this callback.

before_validation :func, on: :action

First thing I did

Implemented using skip_callback and set_callback.

skip_callback(:validation, :before, :func)
------------------------------------------
#Execute processing
------------------------------------------
set_callback(:validation, :before, :func)

However, after that, a problem appeared in other operations, and the cause was investigated.

What are skip_callback and set_callback?

skip_callback can skip the configured callback. However, once executed, it will remain skipped all the time, so you need to use set_callback to return it.

Causes of failure

ʻOn: Because: action` has not been reset.

In other words, the behavior has changed because the callback settings have changed as shown below.

#Before skipping
before_validation :func, on: :action
#After skipping
before_validation :func

Coping

The first set_callback does not specify ʻon :: action`.

set_callback(:validation, :before, :func)

In set_callback, ʻon: action was not set, and ʻon: action was lost.

ʻOn :: action` must be set, so if it is set on, that setting must also be included in the argument.

https://stackoverflow.com/questions/46810340/how-to-set-callback-with-the-on-create-option-in-rails-test

set_callback(:validation, :before, :func, on: :action)

However, even if I tried this, it did not improve.

I checked the source. https://github.com/rails/rails/blob/070d4afacd3e9721b7e3a4634e4d026b5fa2c32c/activesupport/lib/active_support/callbacks.rb#L674

It seems difficult to set ʻon:: action because there are only ʻif, ʻunless, and prepend` in the arguments commented in the source code.

As a final workaround, I decided to use this because there is a method that avoids callbacks and performs processing. https://railsguides.jp/active_record_callbacks.html#%E3%82%B3%E3%83%BC%E3%83%AB%E3%83%90%E3%83%83%E3%82%AF%E3%82%92%E3%82%B9%E3%82%AD%E3%83%83%E3%83%97%E3%81%99%E3%82%8B

Summary

skip_callback and set_callback are convenient methods to avoid callbacks, but if conditions are made using ʻon` and it is okay to avoid all callbacks, callbacks are used in the first place. For now, I'm wondering if it's better to use a method that can avoid.

Recommended Posts

[Rails] on :: Action Conditionally set callback cannot be avoided by using skip_callback and set_callback
[Ruby On Rails] In the create action and destroy action, emergency measures when redirect_to action:: show cannot be (cannot be used)
[Ruby on Rails] How to stop when Rails server cannot be stopped by Ctrl + C