Skip to content
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

feat: extension the Create method of Orm #653

Merged
merged 4 commits into from
Sep 24, 2024
Merged

Conversation

hwbrzzl
Copy link
Contributor

@hwbrzzl hwbrzzl commented Sep 24, 2024

📑 Description

The Create method of Orm supports map:

// Not trigger model events
facades.Orm().Query().Table("users").Create(map[string]any{
  "name": "Goravel",
})

// Trigger model events
facades.Orm().Query().Model(&models.User{}).Create(map[string]any{
  "name": "Goravel",
})

Summary by CodeRabbit

  • New Features

    • Enhanced testing capabilities for attribute setting and retrieval using different data structures (maps and structs).
    • Expanded event handling in the User struct to accommodate various event names and set corresponding attributes.
  • Bug Fixes

    • Improved test coverage for user creation scenarios, ensuring correct handling of IDs and timestamps.
  • Refactor

    • Simplified method signatures and improved clarity in the QueryImpl struct methods.
  • Tests

    • Added new test cases and modified existing ones to cover more scenarios and ensure expected behavior.

✅ Checks

  • Added test cases for my code

Copy link

coderabbitai bot commented Sep 24, 2024

Warning

Rate limit exceeded

@hwbrzzl has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 47 seconds before requesting another review.

How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Commits

Files that changed from the base of the PR and between 7a2854a and ca9c144.

Walkthrough

The changes encompass modifications to the testing and implementation of the SetAttribute method in the EventTestSuite, enhancements to the QueryImpl struct methods, and the addition of new test cases for user creation. The DispatchesEvents method in the User struct has also been updated to handle various event names more effectively. These updates aim to improve the functionality and robustness of the database interaction and testing framework.

Changes

File Path Change Summary
database/gorm/event_test.go Extended the TestSetAttribute method to include tests for setting and retrieving attributes using a struct, in addition to a map.
database/gorm/query.go Refactored methods in QueryImpl to simplify signatures and improve event handling. Moved and redefined the Driver method, and renamed observer to getObserver.
database/gorm/query_test.go Added new test cases for user creation by struct and map, modified existing tests for improved clarity, and updated assertions for expected behavior.
database/gorm/test_models.go Enhanced the DispatchesEvents method in the User struct to handle more specific event names for setting the "avatar" attribute.

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:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    -- I pushed a fix in commit <commit_id>, please review it.
    -- Generate unit testing code for this file.
    • 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. 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

codecov bot commented Sep 24, 2024

Codecov Report

Attention: Patch coverage is 70.51282% with 23 lines in your changes missing coverage. Please review.

Project coverage is 70.40%. Comparing base (ef9e9d6) to head (ca9c144).

Files with missing lines Patch % Lines
database/gorm/query.go 51.06% 4 Missing and 19 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #653      +/-   ##
==========================================
+ Coverage   70.31%   70.40%   +0.08%     
==========================================
  Files         188      188              
  Lines       11645    11677      +32     
==========================================
+ Hits         8188     8221      +33     
+ Misses       2866     2865       -1     
  Partials      591      591              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@hwbrzzl hwbrzzl marked this pull request as ready for review September 24, 2024 03:45
@hwbrzzl hwbrzzl requested a review from a team as a code owner September 24, 2024 03:45
Copy link

@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 (6)
database/gorm/event_test.go (1)

112-138: LGTM! Consider minor refactoring for improved readability.

The new test case for TestSetAttribute with a struct destination is well-implemented and complements the existing test case with a map destination. It thoroughly tests both camel case and lowercase key scenarios, ensuring the SetAttribute and GetAttribute methods work correctly with struct destinations.

To improve code organization and readability, consider extracting the common test logic into a helper function. This would reduce duplication and make it easier to add more test cases in the future if needed.

Here's a suggested refactoring:

func (s *EventTestSuite) TestSetAttribute() {
	testCases := []struct {
		name string
		dest interface{}
	}{
		{"Map Destination", map[string]any{"avatar": "avatar1"}},
		{"Struct Destination", &TestEventModel{Avatar: "avatar1"}},
	}

	for _, tc := range testCases {
		s.Run(tc.name, func() {
			query := &QueryImpl{
				instance: &gorm.DB{
					Statement: &gorm.Statement{
						Selects: []string{},
						Omits:   []string{},
						Dest:    tc.dest,
					},
				},
			}

			event := NewEvent(query, &testEventModel, tc.dest)

			s.testSetAndGetAttribute(event, "Name", "name1")
			s.testSetAndGetAttribute(event, "Avatar", "avatar2")
		})
	}
}

func (s *EventTestSuite) testSetAndGetAttribute(event *Event, key, value string) {
	event.SetAttribute(key, value)
	s.Equal(value, event.GetAttribute(key))
	s.Equal(value, event.GetAttribute(strings.ToLower(key)))
}

This refactoring improves readability, reduces duplication, and makes it easier to add more test cases in the future.

database/gorm/test_models.go (3)

43-51: LGTM: Additional conditions for various creation scenarios.

These new conditions provide more granular control over different creation scenarios, which is beneficial for testing and handling various use cases. The naming conventions are consistent with the existing code.

Consider grouping related conditions together for improved readability. For example:

if name.(string) == "event_creating_by_map_name" {
    event.SetAttribute("avatar", "event_creating_by_map_avatar1")
} else if name.(string) == "event_creating_omit_create_name" {
    event.SetAttribute("avatar", "event_creating_omit_create_avatar")
} else if name.(string) == "event_creating_select_create_name" {
    event.SetAttribute("avatar", "event_creating_select_create_avatar")
} else if name.(string) == "event_creating_save_name" {
    event.SetAttribute("avatar", "event_creating_save_avatar")
}

This grouping can make it easier to understand and maintain related conditions.


75-93: LGTM: Corresponding conditions for "Created" events.

These new conditions align well with the previously added "Creating" event conditions, providing consistency in handling various creation scenarios. The use of record ID in some conditions is appropriate for ensuring uniqueness.

For consistency, consider using the record ID in all new conditions. For example:

if name.(string) == "event_created_by_map_name" {
    id := event.GetAttribute("ID")
    event.SetAttribute("avatar", fmt.Sprintf("event_created_by_map_avatar_%d", id))
}

This change would make all new conditions consistent in their use of the record ID.


147-155: LGTM: Corresponding conditions for "Saved" events.

These new conditions align well with the previously added "Saving" event conditions, providing consistency in handling various saving scenarios. The naming conventions are consistent with the existing code.

For consistency with earlier suggestions, consider using the record ID in these conditions as well. For example:

if name == "event_saved_create_by_map_name" {
    id := event.GetAttribute("ID")
    event.SetAttribute("avatar", fmt.Sprintf("event_saved_create_by_map_avatar_%d", id))
}

This change would make all new conditions consistent in their use of the record ID and align with the earlier suggestions for the "Created" events.

database/gorm/query_test.go (2)

420-463: Clarify the key casing in maps when creating records

The test uses different key casing in maps ("name" vs. "Name", "avatar" vs. "Avatar"). This difference stems from using query.Table("users") (requiring database column names) and query.Model(User{}) (requiring struct field names). Consider adding comments to explain this distinction for future maintainers.


Line range hint 369-578: Consider refactoring tests to reduce code duplication

Multiple test cases within these lines have similar structures and logic, differing mainly in test data and expected outcomes. Refactoring to use table-driven tests can minimize code repetition, improve readability, and make it easier to add new test cases in the future.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between a8d9d6c and 7a2854a.

Files selected for processing (4)
  • database/gorm/event_test.go (2 hunks)
  • database/gorm/query.go (13 hunks)
  • database/gorm/query_test.go (27 hunks)
  • database/gorm/test_models.go (4 hunks)
Additional comments not posted (30)
database/gorm/test_models.go (3)

37-39: LGTM: New condition for map-based creation event.

This addition aligns with the PR objective to support map-based record creation. The naming convention is consistent with other conditions, and the implementation looks correct.


105-107: LGTM: New condition for map-based saving event.

This addition aligns with the new map-based creation functionality and maintains consistency with other conditions in the method. The implementation looks correct.


114-119: LGTM: Additional conditions for various saving scenarios.

These new conditions provide more granular control over different saving scenarios, which is beneficial for testing and handling various use cases. The naming conventions are consistent with the existing code, and the implementation looks correct.

database/gorm/query.go (13)

166-168: Proper implementation of Driver method.

The Driver method correctly returns the driver type using r.instance.Dialector.Name(), ensuring consistent retrieval of the database driver.


Line range hint 598-634: Refactored event handling in Save method for consistency.

The Save method now consistently uses the value parameter in event method calls (saving, updating, updated, saved), enhancing readability and maintaining a uniform interface across methods.


731-745: Consistent event handling in Update method.

The Update method correctly calls event methods (saving, updated, saved) with query.instance.Statement.Dest, ensuring proper event dispatch during updates and aligning with the refactoring to use dest or value.


1136-1151: Simplified create method by using dest parameter in event methods.

Refactoring the create method to use dest directly in event method calls (saving, creating, created, saved) improves clarity by removing unnecessary parameters and aligns with the overall codebase refactoring.


1159-1163: Updated event methods created and creating to use dest.

Simplifying the function signatures by removing the redundant model parameter enhances code maintainability and reduces potential errors.


1190-1191: Corrected event dispatch in event method for custom events.

The implementation properly checks for custom event handlers in the DispatchesEvents map and invokes them when they exist, ensuring custom event logic is executed as expected.


1206-1217: Enhanced observer pattern implementation in event method.

The code accurately retrieves observers for both dest and model and invokes the appropriate event methods using observerEvent, improving the extensibility of the event handling system.


Line range hint 1246-1266: Refactored omitCreate method to use value in event methods.

Consistently using the value parameter in saving and saved event method calls within the omitCreate function enhances code consistency and readability.


1319-1324: Simplified saved and saving methods to use dest parameter.

This change removes unnecessary parameters, aligning with the overall refactoring effort to streamline method signatures.


Line range hint 1340-1354: Consistent use of value in selectCreate event methods.

Updating the selectCreate method to use value in saving and saved event calls maintains consistency across create methods.


1382-1387: Refactored updating and updated methods to use dest.

Simplifying these method signatures by using dest enhances clarity and ensures consistent event handling.


1457-1484: Enhanced getModelConnection to support map types.

By checking if modelType.Kind() is reflect.Map and returning an empty string when true, the function now gracefully handles map types, which is essential for supporting map-based record creation as per the PR objectives.


1492-1495: Renamed observer function to getObserver for clarity.

The function has been renamed to getObserver, which more accurately reflects its purpose of retrieving the observer associated with a given model.

database/gorm/query_test.go (14)

21-21: Importing 'carbon' package is appropriate and necessary

The carbon package is used in the code for handling timestamps (e.g., carbon.Now()). Including this import ensures that the necessary functionality is available.


369-376: Test case 'success by struct' is correctly implemented

This test verifies that a user can be successfully created using a struct. The assertions ensure that the creation operation does not return an error and that the user ID is set.


378-388: Test case 'batch create success by struct' effectively tests batch creation

The test checks the ability to create multiple users in a single operation using a slice of structs. It correctly asserts that all users receive valid IDs upon creation.


390-418: Test case 'success by map' accurately validates map-based creation

This test confirms that users can be created using a map of field values both when specifying the table directly and when using a model. The assertions verify that the users are correctly inserted into the database.


Line range hint 481-488: Test 'success when create with no relationships' appropriately verifies exclusion of associations

The test ensures that when creating a user without specifying associations, the related Address and Books are not saved. The assertions confirm that the IDs for these associations remain zero.


Line range hint 495-502: Test 'success when create with select orm.Associations' confirms associations are created

By selecting orm.Associations, this test verifies that the associated Address and Books are saved along with the user. The assertions correctly check that all IDs are greater than zero.


Line range hint 509-518: Test 'success when create with select fields' validates selective field creation

The test checks that only specified fields and associations ("Name", "Avatar", and "Address") are saved when using Select. It correctly asserts that the Address is created while the Books are not.


Line range hint 523-532: Test 'success when create with omit fields' correctly omits specified association

By omitting the "Address" field, this test ensures that the Address association is not created while other associations (Books) are saved. The assertions confirm this behavior.


Line range hint 537-546: Test 'success create with omit orm.Associations' ensures no associations are saved

This test verifies that when orm.Associations is omitted, none of the associated records are created. The IDs for Address and Books remain zero as expected.


Line range hint 551-558: Proper error handling when using both Select and Omit

The test correctly checks that specifying both Select and Omit triggers an error, as this is not allowed. It asserts that the error message matches the expected output.


Line range hint 561-568: Validating error when combining Select with orm.Associations and fields

This test ensures that selecting both orm.Associations and specific fields results in the appropriate error. It confirms that the operation is invalid and that the error message is as expected.


Line range hint 571-578: Ensuring error is raised when Omit includes both fields and orm.Associations

The test confirms that omitting both specific fields and orm.Associations is not permitted. It correctly asserts that the appropriate error message is returned.


Line range hint 781-790: Test 'trigger when create by struct' correctly verifies event triggering

This test checks that creating a user by struct triggers the expected events, and that the Avatar field is set appropriately. The assertions confirm that the user's data is correctly saved and that the events have the intended effect.


793-807: Verify the correctness of event handling in 'trigger when create by map'

The test expects the Avatar field to be modified during the creation process. Ensure that the event handlers are correctly implemented to modify the Avatar field as intended.

Run the following script to check if the Avatar field is updated during the creation event:

coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 24, 2024
@hwbrzzl hwbrzzl changed the title feat: optimize create feat: extension create Sep 24, 2024
@hwbrzzl hwbrzzl changed the title feat: extension create feat: extension the Create method of Orm Sep 24, 2024
@@ -34,9 +34,21 @@ func (u *User) DispatchesEvents() map[ormcontract.EventType]func(ormcontract.Eve
if name.(string) == "event_creating_name" {
Copy link
Member

Choose a reason for hiding this comment

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

Instead of this, would it be better to cast it? Because if this is not asserted, it will panic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I'll optimize it in another PR.

kkumar-gcc
kkumar-gcc previously approved these changes Sep 24, 2024
@hwbrzzl hwbrzzl merged commit 644ed0a into master Sep 24, 2024
11 of 12 checks passed
@hwbrzzl hwbrzzl deleted the bowen/optimize-create branch September 24, 2024 14:00
@coderabbitai coderabbitai bot mentioned this pull request Sep 28, 2024
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants