cmdx 1.1.0 → 1.1.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/.cursor/prompts/docs.md +9 -0
- data/.cursor/prompts/rspec.md +13 -12
- data/.cursor/prompts/yardoc.md +11 -6
- data/CHANGELOG.md +13 -2
- data/README.md +1 -0
- data/docs/ai_prompts.md +269 -195
- data/docs/basics/call.md +124 -58
- data/docs/basics/chain.md +190 -160
- data/docs/basics/context.md +242 -154
- data/docs/basics/setup.md +302 -32
- data/docs/callbacks.md +390 -94
- data/docs/configuration.md +181 -65
- data/docs/deprecation.md +245 -0
- data/docs/getting_started.md +161 -39
- data/docs/internationalization.md +590 -70
- data/docs/interruptions/exceptions.md +135 -118
- data/docs/interruptions/faults.md +150 -125
- data/docs/interruptions/halt.md +134 -80
- data/docs/logging.md +181 -118
- data/docs/middlewares.md +150 -377
- data/docs/outcomes/result.md +140 -112
- data/docs/outcomes/states.md +134 -99
- data/docs/outcomes/statuses.md +204 -146
- data/docs/parameters/coercions.md +232 -281
- data/docs/parameters/defaults.md +224 -169
- data/docs/parameters/definitions.md +289 -141
- data/docs/parameters/namespacing.md +250 -161
- data/docs/parameters/validations.md +260 -133
- data/docs/testing.md +191 -197
- data/docs/workflows.md +143 -98
- data/lib/cmdx/callback.rb +23 -19
- data/lib/cmdx/callback_registry.rb +1 -3
- data/lib/cmdx/chain_inspector.rb +23 -23
- data/lib/cmdx/chain_serializer.rb +38 -19
- data/lib/cmdx/coercion.rb +20 -12
- data/lib/cmdx/coercion_registry.rb +51 -32
- data/lib/cmdx/configuration.rb +84 -31
- data/lib/cmdx/context.rb +32 -21
- data/lib/cmdx/core_ext/hash.rb +13 -13
- data/lib/cmdx/core_ext/module.rb +1 -1
- data/lib/cmdx/core_ext/object.rb +12 -12
- data/lib/cmdx/correlator.rb +60 -39
- data/lib/cmdx/errors.rb +105 -131
- data/lib/cmdx/fault.rb +66 -45
- data/lib/cmdx/immutator.rb +20 -21
- data/lib/cmdx/lazy_struct.rb +78 -70
- data/lib/cmdx/log_formatters/json.rb +1 -1
- data/lib/cmdx/log_formatters/key_value.rb +1 -1
- data/lib/cmdx/log_formatters/line.rb +1 -1
- data/lib/cmdx/log_formatters/logstash.rb +1 -1
- data/lib/cmdx/log_formatters/pretty_json.rb +1 -1
- data/lib/cmdx/log_formatters/pretty_key_value.rb +1 -1
- data/lib/cmdx/log_formatters/pretty_line.rb +1 -1
- data/lib/cmdx/log_formatters/raw.rb +2 -2
- data/lib/cmdx/logger.rb +19 -14
- data/lib/cmdx/logger_ansi.rb +33 -17
- data/lib/cmdx/logger_serializer.rb +85 -24
- data/lib/cmdx/middleware.rb +39 -21
- data/lib/cmdx/middleware_registry.rb +4 -3
- data/lib/cmdx/parameter.rb +151 -89
- data/lib/cmdx/parameter_inspector.rb +34 -21
- data/lib/cmdx/parameter_registry.rb +36 -30
- data/lib/cmdx/parameter_serializer.rb +21 -14
- data/lib/cmdx/result.rb +136 -135
- data/lib/cmdx/result_ansi.rb +31 -17
- data/lib/cmdx/result_inspector.rb +32 -27
- data/lib/cmdx/result_logger.rb +23 -14
- data/lib/cmdx/result_serializer.rb +65 -27
- data/lib/cmdx/task.rb +234 -113
- data/lib/cmdx/task_deprecator.rb +22 -25
- data/lib/cmdx/task_processor.rb +89 -88
- data/lib/cmdx/task_serializer.rb +27 -14
- data/lib/cmdx/utils/monotonic_runtime.rb +2 -4
- data/lib/cmdx/validator.rb +25 -16
- data/lib/cmdx/validator_registry.rb +53 -31
- data/lib/cmdx/validators/exclusion.rb +1 -1
- data/lib/cmdx/validators/format.rb +2 -2
- data/lib/cmdx/validators/inclusion.rb +2 -2
- data/lib/cmdx/validators/length.rb +2 -2
- data/lib/cmdx/validators/numeric.rb +3 -3
- data/lib/cmdx/validators/presence.rb +2 -2
- data/lib/cmdx/version.rb +1 -1
- data/lib/cmdx/workflow.rb +54 -33
- data/lib/generators/cmdx/task_generator.rb +6 -6
- data/lib/generators/cmdx/workflow_generator.rb +6 -6
- metadata +3 -1
@@ -1,9 +1,6 @@
|
|
1
1
|
# Parameters - Namespacing
|
2
2
|
|
3
|
-
Parameter namespacing provides method name customization to prevent conflicts
|
4
|
-
and enable flexible parameter access patterns. When parameters share names with
|
5
|
-
existing methods or when multiple parameters from different sources have the
|
6
|
-
same name, namespacing ensures clean method resolution within tasks.
|
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.
|
7
4
|
|
8
5
|
## Table of Contents
|
9
6
|
|
@@ -12,158 +9,162 @@ same name, namespacing ensures clean method resolution within tasks.
|
|
12
9
|
- [Fixed Value Namespacing](#fixed-value-namespacing)
|
13
10
|
- [Dynamic Source-Based Namespacing](#dynamic-source-based-namespacing)
|
14
11
|
- [Conflict Resolution](#conflict-resolution)
|
15
|
-
- [Advanced
|
16
|
-
- [Error Handling
|
12
|
+
- [Advanced Patterns](#advanced-patterns)
|
13
|
+
- [Error Handling](#error-handling)
|
17
14
|
|
18
15
|
## TLDR
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
- **Call arguments** - Always use original parameter names, namespacing only affects method names
|
17
|
+
```ruby
|
18
|
+
# Fixed prefixes/suffixes
|
19
|
+
required :name, prefix: "user_" # → user_name method
|
20
|
+
required :email, suffix: "_address" # → email_address method
|
25
21
|
|
26
|
-
|
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
|
27
25
|
|
28
|
-
|
29
|
-
|
26
|
+
# Conflict resolution
|
27
|
+
required :context, suffix: "_data" # Avoids CMDx::Task#context method
|
28
|
+
required :name, prefix: "customer_" # Avoids Ruby's Object#name method
|
30
29
|
|
31
|
-
|
30
|
+
# Call arguments always use original parameter names
|
31
|
+
TaskClass.call(name: "John", email: "john@example.com", context: {...})
|
32
|
+
```
|
32
33
|
|
33
|
-
|
34
|
+
## Namespacing Fundamentals
|
34
35
|
|
35
|
-
|
36
|
-
method names
|
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.
|
37
38
|
|
38
|
-
|
39
|
-
|
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` |
|
40
47
|
|
41
|
-
|
42
|
-
required :width, prefix: "shipping_"
|
43
|
-
required :height, prefix: "shipping_"
|
48
|
+
## Fixed Value Namespacing
|
44
49
|
|
45
|
-
|
46
|
-
required :email, suffix: "_contact"
|
47
|
-
required :phone, suffix: "_contact"
|
50
|
+
Use string or symbol values for consistent prefixes or suffixes:
|
48
51
|
|
49
|
-
|
50
|
-
|
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"
|
51
58
|
|
52
59
|
def call
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
60
|
+
customer = Customer.find(customer_id)
|
61
|
+
customer.update!(
|
62
|
+
name: customer_name,
|
63
|
+
email: email_address,
|
64
|
+
phone: phone_number
|
65
|
+
)
|
59
66
|
end
|
60
|
-
|
61
67
|
end
|
62
68
|
|
63
|
-
# Call
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
email: "
|
68
|
-
phone: "555-
|
69
|
-
weight: 2.5
|
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"
|
70
75
|
)
|
71
76
|
```
|
72
77
|
|
73
|
-
|
78
|
+
## Dynamic Source-Based Namespacing
|
74
79
|
|
75
|
-
|
76
|
-
parameter
|
80
|
+
> [!TIP]
|
81
|
+
> Use `true` with `prefix:` or `suffix:` to automatically generate method names based on parameter sources, creating self-documenting code.
|
77
82
|
|
78
83
|
```ruby
|
79
|
-
class
|
80
|
-
|
81
|
-
|
82
|
-
required :
|
83
|
-
|
84
|
-
# Automatic suffix from custom source
|
85
|
-
required :name, source: :profile, suffix: true # Generates: name_profile
|
86
|
-
|
87
|
-
# Combined automatic namespacing
|
88
|
-
required :email, source: :account, prefix: true, suffix: true # Generates: account_email_account
|
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
|
89
88
|
|
90
89
|
def call
|
91
|
-
|
92
|
-
|
93
|
-
|
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
|
+
)
|
94
99
|
end
|
95
100
|
|
96
101
|
private
|
97
102
|
|
98
|
-
def
|
99
|
-
@
|
103
|
+
def order
|
104
|
+
@order ||= Order.find(context.order_id)
|
100
105
|
end
|
101
106
|
|
102
|
-
def
|
103
|
-
@
|
107
|
+
def settings
|
108
|
+
@settings ||= TaxSettings.for_region(context.region)
|
104
109
|
end
|
105
|
-
|
106
110
|
end
|
107
111
|
```
|
108
112
|
|
109
|
-
> [!NOTE]
|
110
|
-
> Call arguments always use original parameter names regardless of namespacing configuration.
|
111
|
-
|
112
113
|
## Conflict Resolution
|
113
114
|
|
114
|
-
|
115
|
-
|
115
|
+
> [!WARNING]
|
116
|
+
> Parameter names that conflict with existing Ruby or CMDx methods can cause unexpected behavior. Always use namespacing to avoid method collisions.
|
116
117
|
|
117
|
-
### Method
|
118
|
+
### Ruby Method Conflicts
|
118
119
|
|
119
120
|
```ruby
|
120
|
-
class
|
121
|
-
|
122
|
-
|
123
|
-
required :
|
124
|
-
|
125
|
-
# Avoid conflict with custom private methods
|
126
|
-
required :status, suffix: "_param"
|
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
|
127
126
|
|
128
127
|
def call
|
129
|
-
|
130
|
-
|
128
|
+
Account.create!(
|
129
|
+
name: account_name,
|
130
|
+
classification: class_type,
|
131
|
+
request_method: http_method
|
132
|
+
)
|
131
133
|
end
|
134
|
+
end
|
135
|
+
```
|
132
136
|
|
133
|
-
|
137
|
+
### CMDx Method Conflicts
|
134
138
|
|
135
|
-
|
136
|
-
|
137
|
-
|
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
|
138
145
|
|
146
|
+
def call
|
147
|
+
process_data(context_payload, api_result, logger_config)
|
148
|
+
end
|
139
149
|
end
|
140
150
|
```
|
141
151
|
|
142
|
-
###
|
152
|
+
### Multi-Source Disambiguation
|
143
153
|
|
144
154
|
```ruby
|
145
|
-
class
|
146
|
-
|
147
|
-
|
155
|
+
class SyncDataTask < CMDx::Task
|
156
|
+
# Customer and vendor both have overlapping attributes
|
157
|
+
required :id, source: :customer, prefix: "customer_"
|
148
158
|
required :name, source: :customer, prefix: "customer_"
|
149
159
|
required :email, source: :customer, prefix: "customer_"
|
150
160
|
|
151
|
-
|
152
|
-
required :name, source: :
|
153
|
-
required :email, source: :
|
154
|
-
|
155
|
-
# Order information
|
156
|
-
required :total, source: :order, suffix: "_amount"
|
157
|
-
required :status, source: :order, suffix: "_state"
|
161
|
+
required :id, source: :vendor, prefix: "vendor_"
|
162
|
+
required :name, source: :vendor, prefix: "vendor_"
|
163
|
+
required :email, source: :vendor, prefix: "vendor_"
|
158
164
|
|
159
165
|
def call
|
160
|
-
|
161
|
-
|
162
|
-
company_name #=> company.name
|
163
|
-
customer_email #=> customer.email
|
164
|
-
company_email #=> company.email
|
165
|
-
total_amount #=> order.total
|
166
|
-
status_state #=> order.status
|
166
|
+
sync_customer_data(customer_id, customer_name, customer_email)
|
167
|
+
sync_vendor_data(vendor_id, vendor_name, vendor_email)
|
167
168
|
end
|
168
169
|
|
169
170
|
private
|
@@ -172,117 +173,205 @@ class GenerateInvoiceTask < CMDx::Task
|
|
172
173
|
@customer ||= Customer.find(context.customer_id)
|
173
174
|
end
|
174
175
|
|
175
|
-
def
|
176
|
-
@
|
176
|
+
def vendor
|
177
|
+
@vendor ||= Vendor.find(context.vendor_id)
|
177
178
|
end
|
178
|
-
|
179
|
-
def order
|
180
|
-
@order ||= Order.find(context.order_id)
|
181
|
-
end
|
182
|
-
|
183
179
|
end
|
184
180
|
```
|
185
181
|
|
186
|
-
## Advanced
|
187
|
-
|
188
|
-
### Hierarchical Namespacing
|
182
|
+
## Advanced Patterns
|
189
183
|
|
190
|
-
|
184
|
+
### Hierarchical Parameter Organization
|
191
185
|
|
192
186
|
```ruby
|
193
187
|
class CreateShipmentTask < CMDx::Task
|
188
|
+
required :address, source: :origin, prefix: "origin_" do
|
189
|
+
required :street, :city, :state, :zip_code
|
190
|
+
end
|
194
191
|
|
195
|
-
|
196
|
-
|
197
|
-
required :street, :city, :state, :zip
|
192
|
+
required :address, source: :destination, prefix: "destination_" do
|
193
|
+
required :street, :city, :state, :zip_code
|
198
194
|
end
|
199
195
|
|
200
|
-
|
201
|
-
|
202
|
-
|
196
|
+
optional :preferences, suffix: "_config" do
|
197
|
+
required :priority, type: :string
|
198
|
+
optional :signature_required, type: :boolean, default: false
|
203
199
|
end
|
204
200
|
|
205
201
|
def call
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
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
|
+
)
|
212
208
|
end
|
213
209
|
|
214
210
|
private
|
215
211
|
|
216
|
-
def
|
217
|
-
@
|
212
|
+
def origin
|
213
|
+
@origin ||= Address.find(context.origin_address_id)
|
218
214
|
end
|
219
215
|
|
216
|
+
def destination
|
217
|
+
@destination ||= Address.find(context.destination_address_id)
|
218
|
+
end
|
220
219
|
end
|
221
220
|
```
|
222
221
|
|
223
|
-
###
|
224
|
-
|
225
|
-
Apply namespacing based on runtime conditions:
|
222
|
+
### Domain-Specific Grouping
|
226
223
|
|
227
224
|
```ruby
|
228
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
|
229
235
|
|
230
|
-
#
|
231
|
-
required :
|
232
|
-
|
236
|
+
# Merchant processing parameters
|
237
|
+
required :fee_rate, source: :processor, prefix: "processor_", type: :float
|
238
|
+
required :timeout, source: :processor, prefix: "processor_", type: :integer
|
233
239
|
|
234
240
|
def call
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
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
|
+
)
|
241
249
|
end
|
242
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
|
243
260
|
end
|
244
261
|
```
|
245
262
|
|
246
|
-
## Error Handling
|
263
|
+
## Error Handling
|
247
264
|
|
248
|
-
|
249
|
-
|
265
|
+
> [!WARNING]
|
266
|
+
> Validation errors reference namespaced method names, not original parameter names. This affects error message interpretation and debugging.
|
250
267
|
|
251
|
-
|
252
|
-
prefix: "user_",
|
253
|
-
type: :string,
|
254
|
-
format: { with: /@/ }
|
268
|
+
### Validation Error Messages
|
255
269
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
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] }
|
260
275
|
|
261
276
|
def call
|
262
|
-
|
263
|
-
|
264
|
-
|
277
|
+
User.create!(
|
278
|
+
email: user_email,
|
279
|
+
age: age_value,
|
280
|
+
role: account_role
|
281
|
+
)
|
265
282
|
end
|
266
283
|
|
284
|
+
private
|
285
|
+
|
286
|
+
def account
|
287
|
+
@account ||= Account.find(context.account_id)
|
288
|
+
end
|
267
289
|
end
|
268
290
|
|
269
|
-
# Invalid
|
270
|
-
result =
|
291
|
+
# Invalid input produces namespaced error messages
|
292
|
+
result = CreateUserTask.call(
|
271
293
|
email: "invalid-email",
|
272
|
-
age: "
|
294
|
+
age: "fifteen",
|
295
|
+
account: OpenStruct.new(role: "superuser")
|
273
296
|
)
|
274
297
|
|
275
|
-
result.failed?
|
298
|
+
result.failed? # → true
|
276
299
|
result.metadata
|
277
|
-
|
278
|
-
#
|
279
|
-
#
|
280
|
-
#
|
281
|
-
#
|
282
|
-
#
|
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"]
|
283
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
|
284
370
|
```
|
285
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
|
+
|
286
375
|
---
|
287
376
|
|
288
377
|
- **Prev:** [Parameters - Definitions](definitions.md)
|