Class: Treaty::Entity::Attribute::Option::Modifiers::ComputedModifier
- Defined in:
- lib/treaty/entity/attribute/option/modifiers/computed_modifier.rb
Overview
Computes attribute values from all available raw data.
Key Difference from Transform
transform:receives onlyvalue:(the current attribute's value)computed:receives**attributes(ALL raw data from root level)
Usage Examples
Simple mode:
string :full_name, computed: (lambda do |**attributes|
"#{attributes.dig(:user, :first_name)} #{attributes.dig(:user, :last_name)}"
end)
Advanced mode with custom error message:
string :full_name, computed: {
is: ->(**attributes) { "#{attributes.dig(:user, :first_name)} #{attributes.dig(:user, :last_name)}" },
message: "Failed to compute full name"
}
Use Cases
-
Derived fields (full name from parts):
response 200 do object :user do string :first_name string :last_name string :full_name, computed: (lambda do |**attributes| "#{attributes.dig(:user, :first_name)} #{attributes.dig(:user, :last_name)}" end) end end -
Calculated values (word count):
response 200 do object :post do string :content integer :word_count, computed: (lambda do |**attributes| attributes.dig(:post, :content).to_s.split.size end) end end -
Cross-object computations:
response 200 do object :order do integer :quantity integer :unit_price integer :total, computed: (lambda do |**attributes| attributes.dig(:order, :quantity).to_i * attributes.dig(:order, :unit_price).to_i end) end end
Important Notes
- Lambda must accept
**attributes(named argument splat) - Receives full raw data from root level (not just current object)
- Always computes - ignores any existing value, result replaces everything
- All exceptions raised in lambda are caught and re-raised as Validation errors
- Computation is applied during Phase 3 (transformation phase)
- Executes FIRST in modifier chain: computed -> transform -> cast -> default -> as
Advanced Mode
Schema format: { is: lambda, message: nil }
Instance Method Summary collapse
-
#transform_value(_value, root_data = {}) ⇒ Object
Computes value using the provided lambda and full root data Always executes - ignores any existing value.
-
#validate_schema! ⇒ void
Validates that computed value is a lambda.
Methods inherited from Base
#initialize, #target_name, #transforms_name?, #validate_value!
Constructor Details
This class inherits a constructor from Treaty::Entity::Attribute::Option::Base
Instance Method Details
#transform_value(_value, root_data = {}) ⇒ Object
Computes value using the provided lambda and full root data Always executes - ignores any existing value
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/treaty/entity/attribute/option/modifiers/computed_modifier.rb', line 104 def transform_value(_value, root_data = {}) # rubocop:disable Metrics/MethodLength computed_lambda = option_value # Call lambda with full root data as named arguments computed_lambda.call(**root_data) rescue StandardError => e attributes = { attribute: @attribute_name, error: e. } # Catch all exceptions from lambda execution = (**attributes) || I18n.t( "treaty.attributes.modifiers.computed.execution_error", **attributes ) raise Treaty::Exceptions::Validation, end |
#validate_schema! ⇒ void
This method returns an undefined value.
Validates that computed value is a lambda
85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/treaty/entity/attribute/option/modifiers/computed_modifier.rb', line 85 def validate_schema! computed_lambda = option_value return if computed_lambda.respond_to?(:call) raise Treaty::Exceptions::Validation, I18n.t( "treaty.attributes.modifiers.computed.invalid_type", attribute: @attribute_name, type: computed_lambda.class ) end |