Skip to content

Conversation

@takaokouji
Copy link
Collaborator

Problem

When creating a PORO (Plain Old Ruby Object) resource that:

  • Has a model class without the .all method
  • Does NOT override find_by_key
  • Does NOT override find_fragments

The create operation would fail with NoMethodError: undefined method 'all'.

Root Cause

The current implementation of Processor#create_resource calls find_resource_set after creating a resource, which internally calls:

  1. find_fragments
  2. find_fragments_for_non_active_record (for PORO)
  3. find_by_key (default implementation)
  4. records_base
  5. _model_class.all ❌ NoMethodError

Solution

This PR restores the v0.9.x behavior for PORO models: when _model_class doesn't respond to :all, the created resource is passed directly to ResourceSet without attempting to re-fetch it.

ActiveRecord resources continue to use the optimized find_resource_set path with efficient queries and includes.

Changes

  • Modified lib/jsonapi/processor.rb - Added PORO detection in create_resource method
  • Added Test coverage for PORO resources without find_by_key override

Testing

✅ All existing tests pass:

  • Rails 6.1.7.10: 705 runs, 8836 assertions, 0 failures
  • Rails 7.0.10: 705 runs, 8836 assertions, 0 failures
  • Rails 7.1.6: 705 runs, 8842 assertions, 0 failures

✅ New test added: test_create_poro_without_find_by_key_override

Backward Compatibility

This change maintains full backward compatibility:

  • ActiveRecord resources: No behavior change (uses optimized path)
  • PORO with find_by_key override: No behavior change
  • PORO without overrides: Now works correctly (previously failed)

🤖 Generated with Claude Code

Previously, create_resource would call find_resource_set after creating
a PORO resource, which internally calls _model_class.all. This caused
NoMethodError for PORO models that don't have the .all method and
haven't overridden find_by_key.

This fix restores the 0.9.x behavior for PORO models: when the model
class doesn't respond to :all, the created resource is used directly
without attempting to re-fetch it from the database. ActiveRecord
resources continue to use the optimized find_resource_set path.

Changes:
- Modified Processor#create_resource to detect PORO models and handle
  them differently from ActiveRecord models
- Added test coverage for PORO resources without find_by_key override
- All existing tests pass on Rails 6.1, 7.0, and 7.1

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@takaokouji takaokouji merged commit de7f632 into master Jan 23, 2026
61 checks passed
@takaokouji takaokouji deleted the fix/poro-create-without-find-by-key branch January 23, 2026 10:03
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