feat: add WhereHas method
📑 Description
hey there, in this PR I want to add the WhereHas method. I welcome any suggestions. https://github.com/goravel/goravel/issues/373
@coderabbitai summary
✅ Checks
- [ ] Added test cases for my code
[!IMPORTANT]
Review skipped
Auto reviews are limited to specific labels.
Labels to auto review (1)
- 🚀 Review Ready
Please check the settings in the CodeRabbit UI or the
.coderabbit.yamlfile in this repository. To trigger a single review, invoke the@coderabbitai reviewcommand.You can disable this status message by setting the
reviews.review_statustofalsein the CodeRabbit configuration file.
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?
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>. -
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
@coderabbitaiin 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
@coderabbitaiin 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 generate interesting stats about this repository and render them as a table. -
@coderabbitai show all the console.log statements in this repository. -
@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 as PR comments)
-
@coderabbitai pauseto pause the reviews on a PR. -
@coderabbitai resumeto resume the paused reviews. -
@coderabbitai reviewto trigger an incremental review. This is useful when automatic reviews are disabled for the repository. -
@coderabbitai full reviewto do a full review from scratch and review all the files again. -
@coderabbitai summaryto regenerate the summary of the PR. -
@coderabbitai resolveresolve all the CodeRabbit review comments. -
@coderabbitai configurationto show the current CodeRabbit configuration for the repository. -
@coderabbitai helpto get help.
Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
CodeRabbit Configuration File (.coderabbit.yaml)
- You can programmatically configure CodeRabbit by adding a
.coderabbit.yamlfile 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.
Codecov Report
Attention: Patch coverage is 0% with 115 lines in your changes missing coverage. Please review.
Project coverage is 69.26%. Comparing base (
8f0e59e) to head (3d43e5a). Report is 38 commits behind head on master.
Additional details and impacted files
@@ Coverage Diff @@
## master #602 +/- ##
==========================================
- Coverage 69.96% 69.26% -0.71%
==========================================
Files 184 184
Lines 11252 11367 +115
==========================================
Hits 7873 7873
- Misses 2800 2894 +94
- Partials 579 600 +21
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
While working on the code, I noticed that there are no query methods that return errors, nor are there any struct fields like Gorm's Error field. However, errors could potentially occur in these methods. Do you have any suggestions on how we might handle this? I think we can have an Error field like Gorm or panic in errors (I think panic is not a good approach)
The PR is not yet complete, so if you have any other suggestions or ideas to improve it, I'd love to hear them. Thanks! @hwbrzzl
Do you check the Gorm implementation? https://gorm.io/docs/preload.html
Can we use that way to implement WhereHas?
Do you check the Gorm implementation? https://gorm.io/docs/preload.html
Can we use that way to implement WhereHas?
I am familiar with GORM's Preload, but I don't think it's the right solution for us. Preload performs eager loading, which means that even if no related records are found, it will still fetch rows from the original table, but without any related rows. Even if we pass a query function to Preload, it only modifies the select statement for eager loading; the original table rows will still be returned without the related rows.
I didn't find whereHas in gorm like laravel, may I be wrong?
@hwbrzzl
@shayan-yousefi Sorry for the delay, I missed this message. Yes, Gorm doesn't have the WhereHas method, and your explanation about Preload is right. How about the Joins Preloading of Gorm: https://gorm.io/docs/preload.html#Joins-Preloading? Can it be used?
@shayan-yousefi Sorry for the delay, I missed this message. Yes, Gorm doesn't have the WhereHas method, and your explanation about Preload is right. How about the Joins Preloading of Gorm: https://gorm.io/docs/preload.html#Joins-Preloading? Can it be used?
NOTE: Join Preload works with one-to-one relationships, like has one and belongs to.
@hwbrzzl based on the documentation, it's only compatible with has one and belongs to relationships.
One thing to keep in mind is that it limits query statements to using JOIN, which might make writing more complex queries a bit tricky. Also, the GORM documentation mentions that it uses a LEFT JOIN, so it might return rows even if the related rows aren't found.
It seems like Laravel's whereHas might use a nested query since it can handle counts to return rows if a model has a certain number of related rows.
I get the feeling you're not a fan of using reflect. Honestly, neither am I, but I haven't found a better way yet.
If you have a better idea, I'd love to hear it! 🙏 Or if something similar has been implemented before in Goravel, please point me in the right direction so I can get some inspiration.
@shayan-yousefi Thanks for your explanation, basically, I want to use the ready-made methods to reduce the complicated logic, but if there are no other ways, the current logic in this PR is pretty good, we need to find the foreign key and primary key via reflect. And about the error, we can add a private variable to save the error that is returned by WhereHas, and return it when calling the final method, like: Get, First, etc.
@shayan-yousefi Thanks for your explanation, basically, I want to use the ready-made methods to reduce the complicated logic, but if there are no other ways, the current logic in this PR is pretty good, we need to find the foreign key and primary key via reflect. And about the error, we can add a private variable to save the error that is returned by
WhereHas, and return it when calling the final method, like: Get, First, etc.
After some research, I found that we can use gorm.Statement{} by passing the db object to it. By then calling the Parse method with the model, it parses the schema, enabling us to work with it directly without needing to manually handle reflection. @hwbrzzl
Awesome 👍
I find gorm support composit foreignKeys. Are we want to support it? If yes, I have to think in another way @hwbrzzl
@shayan-yousefi Good catch, I think we don't need to support it for now.
@hwbrzzl this PR is done. But I can't run tests to start writing tests. I fix mocks. The issue is that docker containers in test cases always have connection refused error, and I can't run tests to writing them. Am I wrong in running tests, or should I do anything before?
connection refused is normal, after about 60 seconds, the error should disappear. I have a PR to optimize the test process, you can merge it later. https://github.com/goravel/framework/pull/612
I can check the basic logic before you write test cases.
@shayan-yousefi What system are you using?
@shayan-yousefi What system are you using?
what do you mean, system? if you mean os, I use Ubuntu 24.04
Yes, os, got it.
I can check the basic logic before you write test cases.
@hwbrzzl thanks, Are you ok with that? about tests, I think the docker containers do not run correctly, the test fails because it cant never connect to the containers
Yes, Docker should be run. And sorry, I'm on vacation this week, I'll check this PR when I get a chance.
I optimized the docker test experience, please rebase your branch.
@hwbrzzl I will read your reviews. And fix them. Thanks
Hey @shayan-yousefi Are you still working on this, please?
Closed this PR first, feel free to open it when needed.