Skip to content

Conversation

@GautierDele
Copy link
Member

@GautierDele GautierDele commented Aug 20, 2025

closes #189
closes #175

Summary by CodeRabbit

  • New Features
    • Nested relationship includes in search now allowed: include a relation and its nested related records (e.g., parent relation plus its child collection) in one search request.
  • Changes
    • Validation updated so nested include sub-fields are no longer explicitly blocked by this validator, allowing legitimate nested include requests to proceed (other validations may still apply).
  • Tests
    • Added tests covering nested includes for belongs-to → has-many and validation error handling for unauthorized nested includes.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 20, 2025

Walkthrough

Removes the explicit prohibition of the includes sub-field in SearchInclude validation, enabling nested includes. Adds feature tests verifying nested includes for a belongs-to relation including its own has-many relation in search results.

Changes

Cohort / File(s) Summary
Validation: allow nested includes
src/Rules/Search/SearchInclude.php
Deleted the rule that prohibited $attribute.'.includes'. Kept other rules and retained nested validation building via related resource when available.
Tests: nested include behavior
tests/Feature/Controllers/SearchIncludingRelationshipsOperationsTest.php
Added tests asserting nested includes (belongs-to relation including a has-many relation) work in search and that unauthorized nested includes produce validation errors.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor Client
    participant API as Controller
    participant Validator as SearchInclude Validator
    participant Rel as Related Resource Validator
    participant Repo as Data Layer

    Client->>API: POST /api/models/search { search: { includes: [{ relation: A, includes: [{ relation: B }] }] } }
    API->>Validator: Build & run validation rules for includes
    Note over Validator: ".includes" is not prohibited anymore
    Validator->>Rel: Build nested rules for relation A (including its includes)
    Rel-->>Validator: Nested rules for relation B
    Validator-->>API: Validation passes
    API->>Repo: Execute search with nested eager-loads (A, A.B)
    Repo-->>API: Paginated results with nested includes
    API-->>Client: 200 OK with data
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Assessment against linked issues

Objective Addressed Explanation
Enable includes inside includes in search (#189)
Add unit test for include on include (#175)

Poem

I nibbled through the nesting thorn,
Unprohibited paths now brightly born.
Belongs-to hops to has-many glades,
Includes within includes—no more shades!
With whiskered tests, I thump “Hooray!”
Our queries bloom like fields in May. 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between aed897b and b7b5f65.

📒 Files selected for processing (1)
  • tests/Feature/Controllers/SearchIncludingRelationshipsOperationsTest.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/Feature/Controllers/SearchIncludingRelationshipsOperationsTest.php
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/include-in-include

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
tests/Feature/Controllers/SearchIncludingRelationshipsOperationsTest.php (3)

334-339: Stabilize ordering of nested models to avoid flaky assertions

Even though this fixture currently returns a single nested model, future changes (or added factories) could introduce multiple models and non-deterministic ordering. Make the order explicit to keep the test robust.

Apply this minimal diff to ensure a stable order:

-                            'models' => $matchingModelBelongsToRelation->models
-                                ->map(function ($model) {
+                            'models' => $matchingModelBelongsToRelation->models()
+                                ->orderBy('id')
+                                ->get()
+                                ->map(function ($model) {
                                     return $model->only((new ModelResource())->getFields(app()->make(RestRequest::class)));
-                                })
+                                })
                                 ->toArray(),

305-320: Add a negative test to validate nested include errors and error-path keys

Now that nested includes are accepted, we should also assert that unauthorized nested relations fail with the correct error key path (e.g., search.includes.0.includes.0.relation). This complements your existing unauthorized tests for top-level includes.

Here’s a small test you can add alongside this one:

public function test_including_unauthorized_nested_relation_returns_validation_error(): void
{
    Gate::policy(Model::class, GreenPolicy::class);
    Gate::policy(BelongsToRelation::class, GreenPolicy::class);

    $response = $this->post(
        '/api/models/search',
        [
            'search' => [
                'includes' => [
                    [
                        'relation' => 'belongsToRelation',
                        'includes' => [
                            ['relation' => 'unauthorized'],
                        ],
                    ],
                ],
            ],
        ],
        ['Accept' => 'application/json']
    );

    $response->assertStatus(422);
    $response->assertExactJsonStructure(['message', 'errors' => ['search.includes.0.includes.0.relation']]);
}

324-346: Reduce duplication by consolidating with the dot-notation test

This test’s setup and assertions are nearly identical to test_getting_a_list_of_resources_including_belongs_to_has_many_relation. Consider a small refactor (e.g., data provider for the two include syntaxes or a helper that builds the expected structure) to keep the suite DRY and easier to maintain.

If helpful, I can sketch a data provider that feeds both payload shapes into a single test method.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 394f6e9 and aed897b.

📒 Files selected for processing (2)
  • src/Rules/Search/SearchInclude.php (0 hunks)
  • tests/Feature/Controllers/SearchIncludingRelationshipsOperationsTest.php (1 hunks)
💤 Files with no reviewable changes (1)
  • src/Rules/Search/SearchInclude.php
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/Feature/Controllers/SearchIncludingRelationshipsOperationsTest.php (9)
tests/Support/Database/Factories/BelongsToRelationFactory.php (1)
  • BelongsToRelationFactory (8-28)
tests/Support/Database/Factories/ModelFactory.php (1)
  • ModelFactory (8-29)
tests/Support/Models/Model.php (2)
  • Model (10-112)
  • belongsToRelation (23-26)
tests/Support/Models/BelongsToRelation.php (2)
  • BelongsToRelation (7-13)
  • models (9-12)
tests/Support/Traits/InteractsWithResource.php (1)
  • assertResourcePaginated (13-47)
tests/Support/Rest/Resources/ModelResource.php (1)
  • ModelResource (29-160)
tests/Support/Rest/Resources/BelongsToResource.php (1)
  • BelongsToResource (11-31)
src/Concerns/Resource/ConfiguresRestParameters.php (1)
  • getFields (38-41)
src/Http/Requests/RestRequest.php (1)
  • RestRequest (9-23)
🔇 Additional comments (1)
tests/Feature/Controllers/SearchIncludingRelationshipsOperationsTest.php (1)

293-347: Good addition: covers nested include (array syntax) and guards against regressions

This test mirrors the existing dot-notation variant and validates the nested include pathway via the "includes" array. It directly addresses issues #189 and #175. Looks correct and consistent with the surrounding tests and resources.

@GautierDele GautierDele merged commit 887ce27 into main Aug 20, 2025
21 checks passed
@GautierDele GautierDele deleted the feature/include-in-include branch August 20, 2025 16:57
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.

Problem includes inside includes Test include on include

3 participants