Class: Treaty::Attribute::Option::Conditionals::IfConditional
- Defined in:
- lib/treaty/attribute/option/conditionals/if_conditional.rb
Overview
Conditionally includes attributes based on runtime data evaluation.
## Usage Examples
Basic usage with keyword arguments splat:
array :tags, if: ->(**attributes) { attributes.dig(:post, :published_at).present? }
integer :rating, if: ->(**attributes) { attributes.dig(:post, :published_at).present? }
Named argument pattern:
array :tags, if: ->(post:) { post[:published_at].present? }
integer :views, if: ->(post:) { post[:published_at].present? }
Complex conditions:
string :admin_note, if: ->(**attrs) {
attrs.dig(:user, :role) == "admin" && attrs.dig(:post, :flagged)
}
## Use Cases
-
**Show fields only when published**: “‘ruby response 200 do
object :post do string :id string :title datetime :published_at, :optional integer :rating, if: ->(**attrs) { attrs.dig(:post, :published_at).present? } endend # If published_at is nil → rating is excluded from response # If published_at exists → rating is included “‘
-
**Role-based field visibility**: “‘ruby response 200 do
object :user do string :name string :email, if: ->(user:) { user[:role] == "admin" } endend “‘
-
**Nested attribute conditionals**: “‘ruby object :post do
string :title array :tags, if: ->(post:) { post[:published_at].present? } do string :_self endend “‘
## Important Notes
-
Lambda receives raw data as named arguments
-
Lambda MUST return truthy/falsy value
-
If condition is false → attribute is completely omitted
-
If condition is true → attribute is validated and transformed normally
-
All exceptions in lambda are caught and wrapped in Treaty::Exceptions::Validation
-
Does NOT support simple mode (if: true) or advanced mode (if: { is: …, message: … })
## Error Handling
If the lambda raises any exception, it’s caught and converted to a Treaty::Exceptions::Validation with detailed error message including:
-
Attribute name
-
Original exception message
## Data Access Pattern
The lambda receives the same data structure that the orchestrator processes. For nested attributes, you can access parent data using dig:
“‘ruby # For response with { post: { title: “…”, published_at: “…” } } integer :rating, if: ->(**attrs) { attrs.dig(:post, :published_at).present? }
# Alternative: named argument pattern integer :rating, if: ->(post:) { post.present? } “‘
Instance Method Summary collapse
-
#evaluate_condition(data) ⇒ Boolean
Evaluates the conditional lambda with runtime data Returns boolean indicating if attribute should be processed.
-
#validate_schema! ⇒ void
Validates that if option is a callable (Proc/Lambda).
Methods inherited from Base
#transform_value, #validate_value!
Methods inherited from Base
#initialize, #target_name, #transform_value, #transforms_name?, #validate_value!
Constructor Details
This class inherits a constructor from Treaty::Attribute::Option::Base
Instance Method Details
#evaluate_condition(data) ⇒ Boolean
Evaluates the conditional lambda with runtime data Returns boolean indicating if attribute should be processed
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/treaty/attribute/option/conditionals/if_conditional.rb', line 112 def evaluate_condition(data) conditional_lambda = @option_schema # Call lambda with raw data as named arguments # The lambda can use **attributes or specific named args like post: result = conditional_lambda.call(**data) # Convert result to boolean !!result rescue StandardError => e # Catch all exceptions from lambda execution raise Treaty::Exceptions::Validation, I18n.t( "treaty.attributes.conditionals.if.evaluation_error", attribute: @attribute_name, error: e. ) end |
#validate_schema! ⇒ void
This method returns an undefined value.
Validates that if option is a callable (Proc/Lambda)
93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/treaty/attribute/option/conditionals/if_conditional.rb', line 93 def validate_schema! conditional_lambda = @option_schema return if conditional_lambda.respond_to?(:call) raise Treaty::Exceptions::Validation, I18n.t( "treaty.attributes.conditionals.if.invalid_type", attribute: @attribute_name, type: conditional_lambda.class ) end |