rails
rails copied to clipboard
Use `class_attribute` transform block for job config
In #45476, ActiveRecord::Base.destroy_association_async_job
was made to accept a string which would be lazily constantized, to avoid loading ActiveJob::Base
too soon. However, due to the way class_attribute
values are written, each subclass calling destroy_association_async_job
will allocate a _destroy_association_async_job
singleton method regardless of whether the subclass assigns a custom job value.
Additionally, class_attribute
requires using a dummy attribute name so that the post-processing reader method is not overwritten when the attribute is set. This is particularly cumbersome when instance accessors are involved.
This PR re-implements #45476 by adding support for a transform block to class_attribute
. A transform block is applied to an attribute value when that value is first read, and the result is memoized as the actual value of the attribute. Thus, using a transform block, destroy_association_async_job
can lazily constantize and memoize the result, without allocating additional singleton methods, and without juggling attribute names.
The PR also applies the same technique to ActionMailer::Base.delivery_job
. Closes #45486.
I wrote about a few of the alternatives I considered in #45603. Closes #45603.
This is a nice find, and I agree it should be fixed. However I don't think adding this extra feature to class_attributes
is the way to go. Its semantic is already quite complex and I'd rather avoid to complexify it.
Could we instead to this as an eager_load
callback? We could walk down the inheritance tree and resolve the classes as needed.
What do you think?