Skip to content

feat(hooks): optimistic update for nested relations #1842

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 10, 2024
Merged

Conversation

ymc9
Copy link
Member

@ymc9 ymc9 commented Nov 10, 2024

fixes #1840

Copy link
Contributor

coderabbitai bot commented Nov 10, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

This pull request introduces modifications across multiple files, primarily enhancing the testing framework for optimistic updates and nested queries in the Tanstack Query library. New test cases have been added to cover various scenarios related to optimistic updates, while existing tests have been renamed for clarity. Additionally, the modelMeta configuration for the post model has been refined to better define relationships, and significant changes have been made to the mutation application logic in mutator.ts, improving how mutations are applied to data structures.

Changes

File Path Change Summary
packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx Added new test cases for optimistic updates and renamed existing tests for clarity.
packages/plugins/tanstack-query/tests/test-model-meta.ts Updated the post model's ownerId field type and added foreignKeyMapping to the owner field.
packages/runtime/src/cross/mutator.ts Refactored mutation application logic, added new functions for handling mutations, and improved validation checks.

Assessment against linked issues

Objective Addressed Explanation
Enable optimistic updates for related models (1840)

Possibly related PRs


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • 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. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

  • 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: 8

🧹 Outside diff range and nitpick comments (4)
packages/plugins/tanstack-query/tests/test-model-meta.ts (1)

48-55: Well-structured relationship definition!

The explicit foreignKeyMapping addition clearly documents the relationship between Post and User models, which is crucial for implementing optimistic updates across models.

This pattern of explicit foreign key mapping enhances maintainability and makes the relationship between models unambiguous. Consider adopting this pattern consistently across all model relationships in the codebase to facilitate optimistic updates and improve code clarity.

packages/runtime/src/cross/mutator.ts (2)

37-39: Simplify type checking for queryData

The condition can be simplified because arrays are also objects in JavaScript. Checking for typeof queryData !== 'object' is sufficient.

Apply this diff to simplify the condition:

-if (!queryData || (typeof queryData !== 'object' && !Array.isArray(queryData))) {
+if (!queryData || typeof queryData !== 'object') {
     return undefined;
 }

429-445: Handle missing foreign key mappings in assignForeignKeyFields

If field.foreignKeyMapping is undefined, the function exits silently. Consider handling this case to prevent potential issues.

Apply this diff to add a warning when foreign key mapping is missing:

 if (!field.foreignKeyMapping) {
+    if (logging) {
+        console.warn(`No foreign key mapping for field ${field.name}`);
+    }
     return;
 }
packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx (1)

Line range hint 1093-1093: Correct mutation data field in act call

At line 1093, the mutation data uses { name: 'post2' }, but since we're updating a Post, the field should likely be title instead of name.

Apply this diff to correct the field name:

-    mutationResult.current.mutate({ where: { id: '1' }, data: { name: 'post2' } });
+    mutationResult.current.mutate({ where: { id: '1' }, data: { title: 'post2' } });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e59d940 and e0208d7.

📒 Files selected for processing (3)
  • packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx (5 hunks)
  • packages/plugins/tanstack-query/tests/test-model-meta.ts (1 hunks)
  • packages/runtime/src/cross/mutator.ts (9 hunks)
🔇 Additional comments (5)
packages/runtime/src/cross/mutator.ts (1)

275-277: ⚠️ Potential issue

Ensure consistent ID field types in idFieldsMatch

Using strict equality (===) may cause mismatches if ID fields have differing types (e.g., number vs. string). Ensure ID fields are of consistent types or adjust the comparison.

Run the following script to check for inconsistent ID field types:

packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx (4)

626-629: Ensure correct HTTP method for mutations

In the useModelMutation call at lines 626-629, the HTTP method is set to 'PUT' for updating a 'Post'. Ensure that 'PUT' is the correct method for your API. If the API expects 'PATCH' for partial updates, adjust accordingly.

Confirm the expected HTTP method with the backend API specifications.


Line range hint 1268-1268: Ensure consistent handling of non-ZenStack queries

At line 1268, while testing optimistic updates mixed with non-ZenStack queries, verify that the non-ZenStack queries are not affected by the optimistic updates. This is important to maintain isolation between different query types.

Review the query keys and caching strategies to ensure they don't interfere with each other.


389-389: Avoid nesting creates when performing mutations

At line 389, the mutation includes nested creation of posts within a user creation. While Prisma supports nested mutations, it's important to ensure that the backend API handles this correctly. Verify that the backend supports nested creates in this context.

Run the following script to confirm that the backend API endpoint accepts nested creates:

#!/bin/bash
# Description: Check if the 'User' model supports nested 'create' operations with 'posts'.

# Test: Look for 'create' operations in the model definitions that include 'posts'.
rg 'model User' -A 20 | rg 'posts\s*:\s*{\s*create'

344-344: Verify the optimistic update reflects in the cache

At line 344, ensure that the optimistic post added to the user's posts array has all necessary fields and that $optimistic is properly set. This is crucial for the cache to represent the optimistic state accurately.

Run the following script to check the cache data structure:

✅ Verification successful

The optimistic update is correctly reflected in the cache

Based on the test file content, the verification at line 344 is part of a comprehensive test case that checks optimistic updates when creating posts. The test confirms that:

  • The optimistic post is correctly added to the cache with all required fields
  • The $optimistic flag is properly set to true
  • The post contains the expected fields: id, title, and ownerId
  • The values match the expected data: title: 'post1' and ownerId: '1'

The test assertion is accurate and verifies the proper implementation of optimistic updates in the cache.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the optimistic post in the cache has all required fields.

# Test: Retrieve the cache data for the User query and inspect the posts array.
expected_fields=('id' 'title' 'ownerId' '\$optimistic')
rg --json 'getQueryKey.*User.*findMany' | jq '.data' | grep -E "$(IFS='|'; echo "${expected_fields[*]}")"

Length of output: 344


Script:

#!/bin/bash
# Let's analyze the test file to understand the optimistic update implementation
rg -A 10 "\$optimistic.*true" packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx

# Also check the test setup and assertions around optimistic updates
rg -B 5 -A 5 "toMatchObject.*\$optimistic" packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx

# Look for cache-related utility functions
ast-grep --pattern 'function $_(queryClient$_) {
  $$$
}'

Length of output: 258


Script:

#!/bin/bash
# Let's try a different approach to find the test context
cat packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx

# Also look for any optimistic update related patterns
rg -l "optimistic" packages/plugins/tanstack-query/tests/

# Search for cache-related test utilities
rg -l "queryClient" packages/plugins/tanstack-query/tests/

Length of output: 47825

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

🧹 Outside diff range and nitpick comments (1)
packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx (1)

313-318: Mock response should return created data

The mock response for the Post creation returns null, which doesn't match typical API behavior. Consider returning the created post data to better simulate real-world scenarios and ensure proper handling of the actual response.

 nock(makeUrl('Post', 'create'))
     .post(/.*/)
     .reply(200, () => {
         console.log('Not mutating data');
-        return { data: null };
+        return { data: { id: expect.any(String), title: 'post1', ownerId: '1' } };
     });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e0208d7 and 12869c8.

📒 Files selected for processing (1)
  • packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx (7 hunks)
🔇 Additional comments (3)
packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx (3)

593-648: LGTM! Well-structured test for nested relation updates

The test case thoroughly validates the optimistic update behavior when modifying both scalar fields (title) and relationships (owner) of a nested model. It ensures that the cache is properly updated with the optimistic changes.


Line range hint 284-1285: Excellent test coverage for optimistic updates with nested relations

The test suite comprehensively covers:

  • Direct and nested mutations
  • All CRUD operations (create, read, update, delete)
  • Various relationship scenarios
  • Edge cases with null responses

This aligns perfectly with the PR objective of implementing optimistic updates for related models.


996-999: Verify upsert operation structure

The upsert operation's structure should be reviewed to ensure it follows Prisma's specifications. Consider adding comments to clarify the expected behavior of each field in the upsert operation.

✅ Verification successful

Let me search for more specific upsert operations in test files to better understand the context.


Let me try a different search pattern focusing on the test file in question.


Let me try one final search with a broader pattern to understand the test context.


Based on the review of both the original code snippet and the search results from the codebase, I can now provide the final response:

The upsert operation structure is correct and follows Prisma's specifications

The upsert operation in the test follows the standard Prisma upsert structure with the required where, create, and update fields. The structure matches other upsert operations found in the codebase and is being used appropriately in the context of testing optimistic updates for nested relations.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the upsert operation structure in the codebase
# Test: Search for similar upsert operations to confirm the structure
rg -A 5 'upsert.*where.*create.*update'

Length of output: 4286


Script:

#!/bin/bash
# Search for upsert operations specifically in test files under packages/plugins
rg -A 5 'upsert.*where.*create.*update' packages/plugins/

Length of output: 59


Script:

#!/bin/bash
# Search for upsert operations in the specific test file
cat "packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx" | grep -A 10 -B 10 "upsert.*where.*create.*update"

Length of output: 118


Script:

#!/bin/bash
# Get the surrounding context of the upsert operation in the test file
cat "packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx" | grep -A 15 -B 15 "optimistic upsert - update updating nested query"

Length of output: 1185

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