Class: Treaty::Entity::Attribute::Option::Conditionals::IfConditional
- Defined in:
- lib/treaty/entity/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: (lambda do |**attributes|
attributes.dig(:user, :role) == "admin" && attributes.dig(:post, :flagged)
end)
Use Cases
-
Show fields only when published:
response 200 do object :post do string :id string :title datetime :published_at, :optional integer :rating, if: ->(**attributes) { attributes.dig(:post, :published_at).present? } end end # If published_at is nil → rating is excluded from response # If published_at exists → rating is included -
Role-based field visibility:
response 200 do object :user do string :name string :email, if: ->(user:) { user[:role] == "admin" } end end -
Nested attribute conditionals:
object :post do string :title array :tags, if: ->(post:) { post[:published_at].present? } do string :_self end end
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:
# For response with { post: { title: "...", published_at: "..." } }
integer :rating, if: ->(**attributes) { attributes.dig(:post, :published_at).present? }
# Alternative: named argument pattern
integer :rating, if: ->(post:) { post[:published_at].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::Entity::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
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/treaty/entity/attribute/option/conditionals/if_conditional.rb', line 113 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)
94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/treaty/entity/attribute/option/conditionals/if_conditional.rb', line 94 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 |