Skip to content

Derive update fields from the ActiveAdmin form block - #5

Open
lloydwatkin wants to merge 1 commit into
mainfrom
mcp-update-permitted-attributes-error
Open

Derive update fields from the ActiveAdmin form block#5
lloydwatkin wants to merge 1 commit into
mainfrom
mcp-update-permitted-attributes-error

Conversation

@lloydwatkin

Copy link
Copy Markdown
Member

Summary

The MCP update tool could not update any record on resources that declare their writable fields through a form do … end block instead of permit_params. RecordUpdater#permitted_attributes resolved fields solely from the controller's permitted_params; for a form-only resource ActiveAdmin's default permitted_params returns nil, so the tool crashed with:

Could not determine permitted attributes: undefined method '[]' for nil

This blocks a very common ActiveAdmin style — e.g. the consumer that surfaced this has 141 registered resources, only 17 of which declare permit_params while ~92 declare a form block.

Change

  • Prefer the resource's permit_params when it's declared (unchanged behaviour).
  • Otherwise derive the permitted fields from the resource's form block. A new FormFieldCollector runs the form block against a recording stand-in form builder: every input :field records :field; inputs/actions/semantic_errors/helper calls and any other message are swallowed (returning self) so arbitrary Formtastic DSL — as: :hidden, collection: Country.pluck(:name), conditionals, select2 — executes without a real view context. has_many associations are intentionally not descended into (the updater only writes flat attributes).
  • Fail closed: when neither permit_params nor a form block can be resolved, raise rather than silently permitting all columns.

Verification

  • bundle exec rspec — 63 examples, 0 failures (7 new specs covering the form-derivation path, arbitrary DSL tolerance, and both fail-closed cases).
  • Prototyped the collector against a real ActiveAdmin Users::Address resource (whose form calls Country.order(:name).pluck(:name), as: :hidden, select2): it extracts exactly the 12 form fields with no errors.

🤖 Generated with Claude Code

RecordUpdater resolved writable fields solely from the controller's
permitted_params, which only exists when a resource declares
permit_params. Resources that instead declare their fields through a
`form do ... end` block leave ActiveAdmin's default permitted_params
returning nil, so the MCP `update` tool crashed ("undefined method
'[]' for nil") and no record could be updated.

Prefer permit_params when present, and otherwise derive the permitted
fields from the resource's form inputs via a FormFieldCollector that
runs the form block against a recording stand-in builder. Fail closed
when neither can be resolved.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant