Add conditional :if / :unless to ActiveModel::Serialization#include #55016
+546 −6
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
This Pull Request introduces conditional inclusion capabilities to
ActiveModel::Serialization. Currently, when usingserializable_hashwith associations, there isn't a built-in mechanism to conditionally include these associations based on the record's state or other runtime conditions. This often requires developers to implement workarounds, such as creating multiple custom serializers, manually checking conditions before serialization, or implementing complex logic within controllers.This feature adds
:ifand:unlessoptions to the:includedirective, providing a clean, declarative, and idiomatic Rails way to control association inclusion directly within the serialization options, similar to how these options function in other parts of the framework like validations and callbacks.Detail
This Pull Request enhances
ActiveModel::Serialization#serializable_hashto support:ifand:unlessoptions within the:includehash for associations.These options allow developers to specify conditions that determine whether an association should be included in the serialized output. The conditions can be:
SymbolorStringrepresenting an instance method name on the object being serialized.Procthat will be evaluated in the context of the object being serialized usinginstance_exec.Implementation Details:
serializable_add_includesmethod is enhanced to evaluate these conditions before processing an association.should_include_association?(options): Evaluates both:ifand:unlessconditions.evaluate_condition(condition): Handles the evaluation of different condition types (Symbol, Proc, etc.).:if,:unless) are removed from theoptionshash before it's passed down to nestedserializable_hashcalls for the included association, ensuring correct behavior with nested includes.Examples:
The implementation follows Rails conventions, using
instance_execfor Proc evaluation, and is designed to work seamlessly with existing serialization features like:only,:except, and nested includes.Additional information
This feature offers several benefits:
The implementation is designed to be backward compatible. Comprehensive test coverage is included, verifying various condition types, combinations, nested scenarios, and edge cases.
Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]