-
Notifications
You must be signed in to change notification settings - Fork 14
Relation dynamic finders #81
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
Relation dynamic finders #81
Conversation
…at capitalization for attribute names are retained. So the short form for New York is now NY instead of ny. test/model/Author, Book, and Venue now have those strtoupper() workarounds in getter/setter methods removed as it's done in Model.php
…rcased in Model.php in order to be case insensitive.
…at capitalization for attribute names are retained. So the short form for New York is now NY instead of ny. test/model/Author, Book, and Venue now have those strtoupper() workarounds in getter/setter methods removed as it's done in Model.php
…rcased in Model.php in order to be case insensitive.
# Conflicts: # lib/Model.php
…cord # Conflicts: # test/ActiveRecordTest.php # test/models/Book.php
…Disable it so that regression does not timeout.
…d#35: Authors table now has a column that is camel cased: firstName Added tests that demonstrate case insensitivity when accessing this firstName column
- Correct link to contributing.md
…vity() is enough.
…cord # Conflicts: # composer.json # scripts/TestCommand.php
…')->find_by_name('Tito') is possible.
…RecordFindByTest.php and ActiveRecordFromTest.php respectively - In doing the above, found and removed duplicated tests - Added test for Relation::testFindBySelect()
Codecov Report
@@ Coverage Diff @@
## master #81 +/- ##
============================================
+ Coverage 96.59% 96.73% +0.13%
- Complexity 962 964 +2
============================================
Files 33 33
Lines 2351 2358 +7
============================================
+ Hits 2271 2281 +10
+ Misses 80 77 -3
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
|
I'll have to dig into this more deeply later, but are you sure we should support this? Modern versions of Rails seem to encourage the use of |
|
No, but this is quite a useful feature that I would use everywhere in my production code when moving to version 2. The new If you always have to check for an array or a single model throughout your code, it gets tedious and error prone. The workaround I came up with, and I would suggest putting in the documentation is to move to Also, dynamic finders prevent sql injection attacks whereas where() does not in all cases. I don't see any indication in the documentation where dynamic finders are being deprecated, nor would I expect there to be as it's a readable convenience for Ruby on Rails and ActiveRecord. |
Wait, hang on--the new
That's not the case, and never was. You don't have to check if the return type is single or array; you have prior knowledge of what is going to come out the other end based on what you pass in: // always single model (or exception):
$book = Book::find(1);
// always array (or exception)
$books = Book::find([1,2,3]):
// always single model or null
$book = Book::first()
I'm not sure what you mean. As far as I can tell, all of the
Okay, then sounds like we can go with it. |
|
Please make sure to implement the proper static checking extensions. You can basically clone edit: don't forget that we have that weird |
1) Author::order('author_id DESC')->find_by_name('Tito'); would clobber order
2) Author::limit(2)->find_by_name('Tito'); would clobber limit
|
|
Did you mean to close this? |
It's all about the static checking. We already had this set up for Model, such that PHPStan would know to flag this kind of thing as an error: $book = Book::find_by_name("Walden");
if(is_array($book)) { // static analysis error! $book can't be an array, so there is no point in testing it as oneThis kind of magic is currently achieved through the PHPStan reflection class I authored a few weeks back, Now that you've migrated to
It wouldn't. All this work is done in PHPStan extensions. See the files in
Easiest for you, maybe. 😄 But no worries, I'll take care of it this time, but in the future you might consider opening an issue before dropping more bombs like this one so we can identify these kind of issues first. |
…t have side effects on $this->options
| * | ||
| * @return array<TModel> All the rows that matches query. If no rows match, returns [] | ||
| */ | ||
| private function to_a_withOptions(array $options): array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit awkward, isn't it? What are you fixing? If it's related to polluting the user's options with "order" in the case of "having", then you probably won't be surprised to hear that my advice is going to be to move that logic to Table::options_to_sql, and keep the rest of this clean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's to:
- Deny the user to be able to call
Author::to_a($myHandCraftedOptionsThatWouldHaveToBeInputChecked) - Fix the bugs in find_by(), first(), last(), and take(). There are new tests in the test classes which trigger the bug of clobbering $options, but this submission fixes those bugs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Deny the user to be able to call
Author::to_a($myHandCraftedOptionsThatWouldHaveToBeInputChecked)
Is that a thing? There's no static to_a on Model and the to_a on Relation doesn't take any arguments. But let me take a look at your tests...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yep, those tests show the problem, for sure...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public function testDoesNotClobberOrderOrLimit()
{
$rel = Author::limit(2)->order('author_id DESC');
// $this->assertEquals(1, $rel->first()->author_id);The line should not be commented and the test must pass. $author = Author::order('author_id DESC')->first();
$author2 = Author::order('author_id ASC')->last();
$this->assertEquals($author, $author2);As for your other changes, |
The existing code works.
Yes, yes, the tests work even with that line uncommented.
If the tests pass, then the tests pass. 😄 But if you don't like it, we can go with your code and I'll sort it out later. |
|
Thanks! |
Implemented dynamic finders for Relation:
This greatly reduces the need for where clauses, while avoiding the performance hit of retrieving all the columns for a row as in: