Preserve enum methods when using becomes! on STI subclasses #55074
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Motivation / Background
Fixes rails#55001
The
becomes!
method fails to preserve enum-based behavior when converting between STI (Single Table Inheritance) subclasses that define differentenum
values for the same attribute.This is particularly problematic because
enum
defines predicate (#published?
) and mutator (#published!
) methods specific to each class. When switching classes viabecomes!
, the internal type mapping (EnumType
) from the original class is retained, leading to incorrect validation and method behavior.Detail
This change ensures that when performing
becomes!
, each attribute is rebound to the destination class’s attribute type usingwith_type
. This guarantees that enum accessors work correctly in the destination class context.A test case using
LiveParrot
andDeadParrot
subclasses ofParrot
(each declaring their own enum:breed
) demonstrates that the fix allows safe conversion between STI subclasses while maintaining proper enum behavior.Before this change:
This failed due to the original enum mapping from
LiveParrot
being retained.Additional information
EnumType#assert_valid_value
when the new enum value is not recognized by the old enum mapping.(
ActiveRecord::Encryption::EncryptedAttributeType
), such attributes areexplicitly skipped when rebinding types.
Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]