cmdx 1.1.2 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.cursor/prompts/docs.md +4 -1
- data/.cursor/prompts/llms.md +20 -0
- data/.cursor/prompts/rspec.md +4 -1
- data/.cursor/prompts/yardoc.md +3 -2
- data/.cursor/rules/cursor-instructions.mdc +55 -1
- data/.irbrc +6 -0
- data/.rubocop.yml +29 -18
- data/CHANGELOG.md +11 -132
- data/LLM.md +3317 -0
- data/README.md +68 -44
- data/docs/attributes/coercions.md +162 -0
- data/docs/attributes/defaults.md +90 -0
- data/docs/attributes/definitions.md +281 -0
- data/docs/attributes/naming.md +78 -0
- data/docs/attributes/validations.md +309 -0
- data/docs/basics/chain.md +56 -249
- data/docs/basics/context.md +56 -289
- data/docs/basics/execution.md +114 -0
- data/docs/basics/setup.md +37 -334
- data/docs/callbacks.md +89 -467
- data/docs/deprecation.md +91 -174
- data/docs/getting_started.md +212 -202
- data/docs/internationalization.md +11 -647
- data/docs/interruptions/exceptions.md +23 -198
- data/docs/interruptions/faults.md +71 -151
- data/docs/interruptions/halt.md +109 -186
- data/docs/logging.md +44 -256
- data/docs/middlewares.md +113 -426
- data/docs/outcomes/result.md +81 -228
- data/docs/outcomes/states.md +33 -221
- data/docs/outcomes/statuses.md +21 -311
- data/docs/tips_and_tricks.md +120 -70
- data/docs/workflows.md +99 -283
- data/lib/cmdx/.DS_Store +0 -0
- data/lib/cmdx/attribute.rb +229 -0
- data/lib/cmdx/attribute_registry.rb +94 -0
- data/lib/cmdx/attribute_value.rb +193 -0
- data/lib/cmdx/callback_registry.rb +69 -77
- data/lib/cmdx/chain.rb +56 -73
- data/lib/cmdx/coercion_registry.rb +52 -68
- data/lib/cmdx/coercions/array.rb +19 -18
- data/lib/cmdx/coercions/big_decimal.rb +20 -24
- data/lib/cmdx/coercions/boolean.rb +26 -25
- data/lib/cmdx/coercions/complex.rb +21 -22
- data/lib/cmdx/coercions/date.rb +25 -23
- data/lib/cmdx/coercions/date_time.rb +24 -25
- data/lib/cmdx/coercions/float.rb +25 -22
- data/lib/cmdx/coercions/hash.rb +31 -32
- data/lib/cmdx/coercions/integer.rb +30 -24
- data/lib/cmdx/coercions/rational.rb +29 -24
- data/lib/cmdx/coercions/string.rb +19 -22
- data/lib/cmdx/coercions/symbol.rb +37 -0
- data/lib/cmdx/coercions/time.rb +26 -25
- data/lib/cmdx/configuration.rb +49 -108
- data/lib/cmdx/context.rb +222 -44
- data/lib/cmdx/deprecator.rb +61 -0
- data/lib/cmdx/errors.rb +42 -252
- data/lib/cmdx/exceptions.rb +39 -0
- data/lib/cmdx/faults.rb +78 -39
- data/lib/cmdx/freezer.rb +51 -0
- data/lib/cmdx/identifier.rb +30 -0
- data/lib/cmdx/locale.rb +52 -0
- data/lib/cmdx/log_formatters/json.rb +21 -22
- data/lib/cmdx/log_formatters/key_value.rb +20 -22
- data/lib/cmdx/log_formatters/line.rb +15 -22
- data/lib/cmdx/log_formatters/logstash.rb +22 -23
- data/lib/cmdx/log_formatters/raw.rb +16 -22
- data/lib/cmdx/middleware_registry.rb +70 -74
- data/lib/cmdx/middlewares/correlate.rb +90 -54
- data/lib/cmdx/middlewares/runtime.rb +58 -0
- data/lib/cmdx/middlewares/timeout.rb +48 -68
- data/lib/cmdx/railtie.rb +12 -45
- data/lib/cmdx/result.rb +229 -314
- data/lib/cmdx/task.rb +194 -366
- data/lib/cmdx/utils/call.rb +49 -0
- data/lib/cmdx/utils/condition.rb +71 -0
- data/lib/cmdx/utils/format.rb +61 -0
- data/lib/cmdx/validator_registry.rb +63 -72
- data/lib/cmdx/validators/exclusion.rb +38 -67
- data/lib/cmdx/validators/format.rb +48 -49
- data/lib/cmdx/validators/inclusion.rb +43 -74
- data/lib/cmdx/validators/length.rb +101 -162
- data/lib/cmdx/validators/numeric.rb +95 -170
- data/lib/cmdx/validators/presence.rb +37 -50
- data/lib/cmdx/version.rb +1 -1
- data/lib/cmdx/worker.rb +178 -0
- data/lib/cmdx/workflow.rb +85 -81
- data/lib/cmdx.rb +19 -13
- data/lib/generators/cmdx/install_generator.rb +14 -13
- data/lib/generators/cmdx/task_generator.rb +25 -50
- data/lib/generators/cmdx/templates/install.rb +11 -46
- data/lib/generators/cmdx/templates/task.rb.tt +3 -2
- data/lib/locales/en.yml +18 -4
- data/src/cmdx-logo.png +0 -0
- metadata +32 -116
- data/docs/ai_prompts.md +0 -393
- data/docs/basics/call.md +0 -317
- data/docs/configuration.md +0 -344
- data/docs/parameters/coercions.md +0 -396
- data/docs/parameters/defaults.md +0 -335
- data/docs/parameters/definitions.md +0 -446
- data/docs/parameters/namespacing.md +0 -378
- data/docs/parameters/validations.md +0 -405
- data/docs/testing.md +0 -553
- data/lib/cmdx/callback.rb +0 -53
- data/lib/cmdx/chain_inspector.rb +0 -56
- data/lib/cmdx/chain_serializer.rb +0 -63
- data/lib/cmdx/coercion.rb +0 -57
- data/lib/cmdx/coercions/virtual.rb +0 -29
- data/lib/cmdx/core_ext/hash.rb +0 -83
- data/lib/cmdx/core_ext/module.rb +0 -98
- data/lib/cmdx/core_ext/object.rb +0 -125
- data/lib/cmdx/correlator.rb +0 -122
- data/lib/cmdx/error.rb +0 -67
- data/lib/cmdx/fault.rb +0 -140
- data/lib/cmdx/immutator.rb +0 -52
- data/lib/cmdx/lazy_struct.rb +0 -246
- data/lib/cmdx/log_formatters/pretty_json.rb +0 -40
- data/lib/cmdx/log_formatters/pretty_key_value.rb +0 -38
- data/lib/cmdx/log_formatters/pretty_line.rb +0 -41
- data/lib/cmdx/logger.rb +0 -49
- data/lib/cmdx/logger_ansi.rb +0 -68
- data/lib/cmdx/logger_serializer.rb +0 -116
- data/lib/cmdx/middleware.rb +0 -70
- data/lib/cmdx/parameter.rb +0 -312
- data/lib/cmdx/parameter_evaluator.rb +0 -231
- data/lib/cmdx/parameter_inspector.rb +0 -66
- data/lib/cmdx/parameter_registry.rb +0 -106
- data/lib/cmdx/parameter_serializer.rb +0 -59
- data/lib/cmdx/result_ansi.rb +0 -71
- data/lib/cmdx/result_inspector.rb +0 -71
- data/lib/cmdx/result_logger.rb +0 -59
- data/lib/cmdx/result_serializer.rb +0 -104
- data/lib/cmdx/rspec/matchers.rb +0 -28
- data/lib/cmdx/rspec/result_matchers/be_executed.rb +0 -42
- data/lib/cmdx/rspec/result_matchers/be_failed_task.rb +0 -94
- data/lib/cmdx/rspec/result_matchers/be_skipped_task.rb +0 -94
- data/lib/cmdx/rspec/result_matchers/be_state_matchers.rb +0 -59
- data/lib/cmdx/rspec/result_matchers/be_status_matchers.rb +0 -57
- data/lib/cmdx/rspec/result_matchers/be_successful_task.rb +0 -87
- data/lib/cmdx/rspec/result_matchers/have_bad_outcome.rb +0 -51
- data/lib/cmdx/rspec/result_matchers/have_caused_failure.rb +0 -58
- data/lib/cmdx/rspec/result_matchers/have_chain_index.rb +0 -59
- data/lib/cmdx/rspec/result_matchers/have_context.rb +0 -86
- data/lib/cmdx/rspec/result_matchers/have_empty_metadata.rb +0 -54
- data/lib/cmdx/rspec/result_matchers/have_good_outcome.rb +0 -52
- data/lib/cmdx/rspec/result_matchers/have_metadata.rb +0 -114
- data/lib/cmdx/rspec/result_matchers/have_preserved_context.rb +0 -66
- data/lib/cmdx/rspec/result_matchers/have_received_thrown_failure.rb +0 -64
- data/lib/cmdx/rspec/result_matchers/have_runtime.rb +0 -78
- data/lib/cmdx/rspec/result_matchers/have_thrown_failure.rb +0 -76
- data/lib/cmdx/rspec/task_matchers/be_well_formed_task.rb +0 -62
- data/lib/cmdx/rspec/task_matchers/have_callback.rb +0 -85
- data/lib/cmdx/rspec/task_matchers/have_cmd_setting.rb +0 -68
- data/lib/cmdx/rspec/task_matchers/have_executed_callbacks.rb +0 -92
- data/lib/cmdx/rspec/task_matchers/have_middleware.rb +0 -46
- data/lib/cmdx/rspec/task_matchers/have_parameter.rb +0 -181
- data/lib/cmdx/task_deprecator.rb +0 -58
- data/lib/cmdx/task_processor.rb +0 -246
- data/lib/cmdx/task_serializer.rb +0 -57
- data/lib/cmdx/utils/ansi_color.rb +0 -73
- data/lib/cmdx/utils/log_timestamp.rb +0 -36
- data/lib/cmdx/utils/monotonic_runtime.rb +0 -34
- data/lib/cmdx/utils/name_affix.rb +0 -52
- data/lib/cmdx/validator.rb +0 -57
- data/lib/generators/cmdx/templates/workflow.rb.tt +0 -7
- data/lib/generators/cmdx/workflow_generator.rb +0 -84
- data/lib/locales/ar.yml +0 -35
- data/lib/locales/cs.yml +0 -35
- data/lib/locales/da.yml +0 -35
- data/lib/locales/de.yml +0 -35
- data/lib/locales/el.yml +0 -35
- data/lib/locales/es.yml +0 -35
- data/lib/locales/fi.yml +0 -35
- data/lib/locales/fr.yml +0 -35
- data/lib/locales/he.yml +0 -35
- data/lib/locales/hi.yml +0 -35
- data/lib/locales/it.yml +0 -35
- data/lib/locales/ja.yml +0 -35
- data/lib/locales/ko.yml +0 -35
- data/lib/locales/nl.yml +0 -35
- data/lib/locales/no.yml +0 -35
- data/lib/locales/pl.yml +0 -35
- data/lib/locales/pt.yml +0 -35
- data/lib/locales/ru.yml +0 -35
- data/lib/locales/sv.yml +0 -35
- data/lib/locales/th.yml +0 -35
- data/lib/locales/tr.yml +0 -35
- data/lib/locales/vi.yml +0 -35
- data/lib/locales/zh.yml +0 -35
@@ -1,378 +0,0 @@
|
|
1
|
-
# Parameters - Namespacing
|
2
|
-
|
3
|
-
Parameter namespacing provides method name customization to prevent conflicts and enable flexible parameter access patterns. When parameters share names with existing methods or when multiple parameters from different sources have the same name, namespacing ensures clean method resolution within tasks.
|
4
|
-
|
5
|
-
## Table of Contents
|
6
|
-
|
7
|
-
- [TLDR](#tldr)
|
8
|
-
- [Namespacing Fundamentals](#namespacing-fundamentals)
|
9
|
-
- [Fixed Value Namespacing](#fixed-value-namespacing)
|
10
|
-
- [Dynamic Source-Based Namespacing](#dynamic-source-based-namespacing)
|
11
|
-
- [Conflict Resolution](#conflict-resolution)
|
12
|
-
- [Advanced Patterns](#advanced-patterns)
|
13
|
-
- [Error Handling](#error-handling)
|
14
|
-
|
15
|
-
## TLDR
|
16
|
-
|
17
|
-
```ruby
|
18
|
-
# Fixed prefixes/suffixes
|
19
|
-
required :name, prefix: "user_" # → user_name method
|
20
|
-
required :email, suffix: "_address" # → email_address method
|
21
|
-
|
22
|
-
# Dynamic source-based namespacing
|
23
|
-
required :id, prefix: true # → context_id method (from context source)
|
24
|
-
required :name, source: :profile, suffix: true # → name_profile method
|
25
|
-
|
26
|
-
# Conflict resolution
|
27
|
-
required :context, suffix: "_data" # Avoids CMDx::Task#context method
|
28
|
-
required :name, prefix: "customer_" # Avoids Ruby's Object#name method
|
29
|
-
|
30
|
-
# Call arguments always use original parameter names
|
31
|
-
TaskClass.call(name: "John", email: "john@example.com", context: {...})
|
32
|
-
```
|
33
|
-
|
34
|
-
## Namespacing Fundamentals
|
35
|
-
|
36
|
-
> [!IMPORTANT]
|
37
|
-
> Namespacing modifies only the generated accessor method names within tasks. Parameter names in call arguments remain unchanged, ensuring a clean external interface.
|
38
|
-
|
39
|
-
### Namespacing Options
|
40
|
-
|
41
|
-
| Option | Type | Description | Example |
|
42
|
-
|--------|------|-------------|---------|
|
43
|
-
| `prefix:` | String/Symbol | Fixed prefix | `prefix: "user_"` → `user_name` |
|
44
|
-
| `prefix:` | Boolean | Dynamic prefix from source | `prefix: true` → `context_name` |
|
45
|
-
| `suffix:` | String/Symbol | Fixed suffix | `suffix: "_data"` → `name_data` |
|
46
|
-
| `suffix:` | Boolean | Dynamic suffix from source | `suffix: true` → `name_context` |
|
47
|
-
|
48
|
-
## Fixed Value Namespacing
|
49
|
-
|
50
|
-
Use string or symbol values for consistent prefixes or suffixes:
|
51
|
-
|
52
|
-
```ruby
|
53
|
-
class UpdateCustomerTask < CMDx::Task
|
54
|
-
required :id, prefix: "customer_"
|
55
|
-
required :name, prefix: "customer_"
|
56
|
-
required :email, suffix: "_address"
|
57
|
-
required :phone, suffix: "_number"
|
58
|
-
|
59
|
-
def call
|
60
|
-
customer = Customer.find(customer_id)
|
61
|
-
customer.update!(
|
62
|
-
name: customer_name,
|
63
|
-
email: email_address,
|
64
|
-
phone: phone_number
|
65
|
-
)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# Call uses original parameter names
|
70
|
-
UpdateCustomerTask.call(
|
71
|
-
id: 123,
|
72
|
-
name: "Jane Smith",
|
73
|
-
email: "jane@example.com",
|
74
|
-
phone: "555-0123"
|
75
|
-
)
|
76
|
-
```
|
77
|
-
|
78
|
-
## Dynamic Source-Based Namespacing
|
79
|
-
|
80
|
-
> [!TIP]
|
81
|
-
> Use `true` with `prefix:` or `suffix:` to automatically generate method names based on parameter sources, creating self-documenting code.
|
82
|
-
|
83
|
-
```ruby
|
84
|
-
class GenerateInvoiceTask < CMDx::Task
|
85
|
-
required :id, prefix: true # → context_id
|
86
|
-
required :amount, source: :order, prefix: true # → order_amount
|
87
|
-
required :tax_rate, source: :settings, suffix: true # → tax_rate_settings
|
88
|
-
|
89
|
-
def call
|
90
|
-
customer = Customer.find(context_id)
|
91
|
-
total = order_amount * (1 + tax_rate_settings)
|
92
|
-
|
93
|
-
Invoice.create!(
|
94
|
-
customer: customer,
|
95
|
-
amount: order_amount,
|
96
|
-
tax_rate: tax_rate_settings,
|
97
|
-
total: total
|
98
|
-
)
|
99
|
-
end
|
100
|
-
|
101
|
-
private
|
102
|
-
|
103
|
-
def order
|
104
|
-
@order ||= Order.find(context.order_id)
|
105
|
-
end
|
106
|
-
|
107
|
-
def settings
|
108
|
-
@settings ||= TaxSettings.for_region(context.region)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
```
|
112
|
-
|
113
|
-
## Conflict Resolution
|
114
|
-
|
115
|
-
> [!WARNING]
|
116
|
-
> Parameter names that conflict with existing Ruby or CMDx methods can cause unexpected behavior. Always use namespacing to avoid method collisions.
|
117
|
-
|
118
|
-
### Ruby Method Conflicts
|
119
|
-
|
120
|
-
```ruby
|
121
|
-
class ProcessAccountTask < CMDx::Task
|
122
|
-
# Avoid conflicts with Ruby's built-in methods
|
123
|
-
required :name, prefix: "account_" # Not Object#name
|
124
|
-
required :class, suffix: "_type" # Not Object#class
|
125
|
-
required :method, prefix: "http_" # Not Object#method
|
126
|
-
|
127
|
-
def call
|
128
|
-
Account.create!(
|
129
|
-
name: account_name,
|
130
|
-
classification: class_type,
|
131
|
-
request_method: http_method
|
132
|
-
)
|
133
|
-
end
|
134
|
-
end
|
135
|
-
```
|
136
|
-
|
137
|
-
### CMDx Method Conflicts
|
138
|
-
|
139
|
-
```ruby
|
140
|
-
class DataProcessingTask < CMDx::Task
|
141
|
-
# Avoid conflicts with CMDx::Task methods
|
142
|
-
required :context, suffix: "_payload" # Not CMDx::Task#context
|
143
|
-
required :result, prefix: "api_" # Not CMDx::Task#result
|
144
|
-
required :logger, suffix: "_config" # Not CMDx::Task#logger
|
145
|
-
|
146
|
-
def call
|
147
|
-
process_data(context_payload, api_result, logger_config)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
```
|
151
|
-
|
152
|
-
### Multi-Source Disambiguation
|
153
|
-
|
154
|
-
```ruby
|
155
|
-
class SyncDataTask < CMDx::Task
|
156
|
-
# Customer and vendor both have overlapping attributes
|
157
|
-
required :id, source: :customer, prefix: "customer_"
|
158
|
-
required :name, source: :customer, prefix: "customer_"
|
159
|
-
required :email, source: :customer, prefix: "customer_"
|
160
|
-
|
161
|
-
required :id, source: :vendor, prefix: "vendor_"
|
162
|
-
required :name, source: :vendor, prefix: "vendor_"
|
163
|
-
required :email, source: :vendor, prefix: "vendor_"
|
164
|
-
|
165
|
-
def call
|
166
|
-
sync_customer_data(customer_id, customer_name, customer_email)
|
167
|
-
sync_vendor_data(vendor_id, vendor_name, vendor_email)
|
168
|
-
end
|
169
|
-
|
170
|
-
private
|
171
|
-
|
172
|
-
def customer
|
173
|
-
@customer ||= Customer.find(context.customer_id)
|
174
|
-
end
|
175
|
-
|
176
|
-
def vendor
|
177
|
-
@vendor ||= Vendor.find(context.vendor_id)
|
178
|
-
end
|
179
|
-
end
|
180
|
-
```
|
181
|
-
|
182
|
-
## Advanced Patterns
|
183
|
-
|
184
|
-
### Hierarchical Parameter Organization
|
185
|
-
|
186
|
-
```ruby
|
187
|
-
class CreateShipmentTask < CMDx::Task
|
188
|
-
required :address, source: :origin, prefix: "origin_" do
|
189
|
-
required :street, :city, :state, :zip_code
|
190
|
-
end
|
191
|
-
|
192
|
-
required :address, source: :destination, prefix: "destination_" do
|
193
|
-
required :street, :city, :state, :zip_code
|
194
|
-
end
|
195
|
-
|
196
|
-
optional :preferences, suffix: "_config" do
|
197
|
-
required :priority, type: :string
|
198
|
-
optional :signature_required, type: :boolean, default: false
|
199
|
-
end
|
200
|
-
|
201
|
-
def call
|
202
|
-
shipment = Shipment.create!(
|
203
|
-
origin_address: origin_address,
|
204
|
-
destination_address: destination_address,
|
205
|
-
priority: preferences_config[:priority],
|
206
|
-
signature_required: preferences_config[:signature_required]
|
207
|
-
)
|
208
|
-
end
|
209
|
-
|
210
|
-
private
|
211
|
-
|
212
|
-
def origin
|
213
|
-
@origin ||= Address.find(context.origin_address_id)
|
214
|
-
end
|
215
|
-
|
216
|
-
def destination
|
217
|
-
@destination ||= Address.find(context.destination_address_id)
|
218
|
-
end
|
219
|
-
end
|
220
|
-
```
|
221
|
-
|
222
|
-
### Domain-Specific Grouping
|
223
|
-
|
224
|
-
```ruby
|
225
|
-
class ProcessPaymentTask < CMDx::Task
|
226
|
-
# Payment-related parameters
|
227
|
-
required :amount, prefix: "payment_", type: :big_decimal
|
228
|
-
required :currency, prefix: "payment_", type: :string
|
229
|
-
required :method, prefix: "payment_", type: :string
|
230
|
-
|
231
|
-
# Customer billing parameters
|
232
|
-
required :address, source: :billing, prefix: "billing_" do
|
233
|
-
required :street, :city, :country
|
234
|
-
end
|
235
|
-
|
236
|
-
# Merchant processing parameters
|
237
|
-
required :fee_rate, source: :processor, prefix: "processor_", type: :float
|
238
|
-
required :timeout, source: :processor, prefix: "processor_", type: :integer
|
239
|
-
|
240
|
-
def call
|
241
|
-
charge = PaymentProcessor.charge(
|
242
|
-
amount: payment_amount,
|
243
|
-
currency: payment_currency,
|
244
|
-
method: payment_method,
|
245
|
-
billing_address: billing_address,
|
246
|
-
processor_fee: payment_amount * processor_fee_rate,
|
247
|
-
timeout: processor_timeout
|
248
|
-
)
|
249
|
-
end
|
250
|
-
|
251
|
-
private
|
252
|
-
|
253
|
-
def billing
|
254
|
-
@billing ||= BillingAddress.find(context.billing_address_id)
|
255
|
-
end
|
256
|
-
|
257
|
-
def processor
|
258
|
-
@processor ||= PaymentProcessor.for_method(payment_method)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
```
|
262
|
-
|
263
|
-
## Error Handling
|
264
|
-
|
265
|
-
> [!WARNING]
|
266
|
-
> Validation errors reference namespaced method names, not original parameter names. This affects error message interpretation and debugging.
|
267
|
-
|
268
|
-
### Validation Error Messages
|
269
|
-
|
270
|
-
```ruby
|
271
|
-
class CreateUserTask < CMDx::Task
|
272
|
-
required :email, prefix: "user_", format: { with: /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i }
|
273
|
-
required :age, suffix: "_value", type: :integer, numeric: { min: 18, max: 120 }
|
274
|
-
required :role, source: :account, prefix: "account_", inclusion: { in: %w[admin user guest] }
|
275
|
-
|
276
|
-
def call
|
277
|
-
User.create!(
|
278
|
-
email: user_email,
|
279
|
-
age: age_value,
|
280
|
-
role: account_role
|
281
|
-
)
|
282
|
-
end
|
283
|
-
|
284
|
-
private
|
285
|
-
|
286
|
-
def account
|
287
|
-
@account ||= Account.find(context.account_id)
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
# Invalid input produces namespaced error messages
|
292
|
-
result = CreateUserTask.call(
|
293
|
-
email: "invalid-email",
|
294
|
-
age: "fifteen",
|
295
|
-
account: OpenStruct.new(role: "superuser")
|
296
|
-
)
|
297
|
-
|
298
|
-
result.failed? # → true
|
299
|
-
result.metadata
|
300
|
-
# {
|
301
|
-
# reason: "user_email format is not valid. age_value could not coerce into an integer. account_role inclusion is not valid.",
|
302
|
-
# messages: {
|
303
|
-
# user_email: ["format is not valid"],
|
304
|
-
# age_value: ["could not coerce into an integer"],
|
305
|
-
# account_role: ["inclusion is not valid"]
|
306
|
-
# }
|
307
|
-
# }
|
308
|
-
```
|
309
|
-
|
310
|
-
### Common Namespacing Mistakes
|
311
|
-
|
312
|
-
```ruby
|
313
|
-
class ProblematicTask < CMDx::Task
|
314
|
-
required :data, prefix: "user_"
|
315
|
-
required :config, source: :settings, suffix: "_data"
|
316
|
-
|
317
|
-
def call
|
318
|
-
# ❌ WRONG: Using original parameter names in task methods
|
319
|
-
process(data) # NoMethodError: undefined method `data`
|
320
|
-
apply(config) # NoMethodError: undefined method `config`
|
321
|
-
|
322
|
-
# ✅ CORRECT: Using namespaced method names
|
323
|
-
process(user_data) # Works correctly
|
324
|
-
apply(config_data) # Works correctly
|
325
|
-
end
|
326
|
-
|
327
|
-
private
|
328
|
-
|
329
|
-
def settings
|
330
|
-
@settings ||= AppSettings.current
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
# ❌ WRONG: Using namespaced names in call arguments
|
335
|
-
ProblematicTask.call(
|
336
|
-
user_data: { name: "John" }, # ArgumentError: unknown parameter
|
337
|
-
config_data: { theme: "dark" } # ArgumentError: unknown parameter
|
338
|
-
)
|
339
|
-
|
340
|
-
# ✅ CORRECT: Using original parameter names in call arguments
|
341
|
-
ProblematicTask.call(
|
342
|
-
data: { name: "John" }, # Correct
|
343
|
-
config: { theme: "dark" } # Correct
|
344
|
-
)
|
345
|
-
```
|
346
|
-
|
347
|
-
### Debugging Namespaced Parameters
|
348
|
-
|
349
|
-
```ruby
|
350
|
-
class DebuggingTask < CMDx::Task
|
351
|
-
required :id, prefix: "user_"
|
352
|
-
required :data, source: :profile, suffix: "_payload"
|
353
|
-
|
354
|
-
def call
|
355
|
-
# Use introspection to understand parameter mapping
|
356
|
-
puts "Available methods: #{methods.grep(/^(user_|.*_payload$)/)}"
|
357
|
-
# → ["user_id", "data_payload"]
|
358
|
-
|
359
|
-
# Access parameters using correct namespaced names
|
360
|
-
user = User.find(user_id)
|
361
|
-
user.update!(data_payload)
|
362
|
-
end
|
363
|
-
|
364
|
-
private
|
365
|
-
|
366
|
-
def profile
|
367
|
-
@profile ||= UserProfile.find(context.profile_id)
|
368
|
-
end
|
369
|
-
end
|
370
|
-
```
|
371
|
-
|
372
|
-
> [!NOTE]
|
373
|
-
> When debugging namespaced parameters, remember that error messages, method introspection, and stack traces will show the namespaced method names, not the original parameter names used in task calls.
|
374
|
-
|
375
|
-
---
|
376
|
-
|
377
|
-
- **Prev:** [Parameters - Definitions](definitions.md)
|
378
|
-
- **Next:** [Parameters - Coercions](coercions.md)
|