-
Notifications
You must be signed in to change notification settings - Fork 442
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
test for finding by null #420
Conversation
I'm not sure I am convinced of the utility of this change. It seems to me that this is a user code error because one should not be searching for records in a RDBMS via a |
That's what I'm doing. Added a custom exception message for invalid key argument. I snooped around a bit in the rails code to see what they do. Someone who can read Ruby better than me will have to help, but it looks to me like they just do the standard RecordNotFound exception. https://github.com/rails/rails/blob/master/activerecord/lib/active_record/core.rb |
I went poking into their tests, and the plot thickens, a bit: https://github.com/rails/rails/blob/master/activerecord/test/cases/finder_test.rb They have a test called "test_find_an_empty_array", which expects an empty array as a result. Strangely, they have another test called "test_find_by_empty_ids" which seems to do the same exact thing. def test_find_by_empty_ids
assert_equal [], Post.find([])
end
def test_find_an_empty_array
assert_equal [], Topic.find([])
end I don't see any tests for null being passed in, but apparently in at least some cases an empty result set can be returned. |
I believe we have the find_by_array equivalent in PHP-AR which returns an empty array. That is not the same behavior as a single $id or null. |
@jpfuentes2 |
Kinda, but I don't have any DB stuff setup. I went from PHP -> Ruby -> Scala so I don't do much Ruby these days either. |
I don't think it raises a specific exception. I think |
Groovy. Let me know if anything else seems suspicious. |
@@ -1581,19 +1581,23 @@ public static function find(/* $type, $options */) | |||
*/ | |||
public static function find_by_pk($values, $options) | |||
{ | |||
if(is_null($values)){ |
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.
if (expr)
{
}
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.
Or
if (expr)
expr
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.
null === $values
is faster than is_null($values)
Should we be checking explicit null or empty here?
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.
Well, we could check for empty, but then that will change the existing behavior for passing in "0" and empty array.
Rebased on master. |
By the way, is there anything I can do to help get some of these older PRs up to date, passing tests, etc? |
Oh well, I just did it: https://github.com/jpfuentes2/php-activerecord/tree/1.1-dev |
@koenpunt So how can I help? |
Review any of the open todo's on #430 and submit a rebased version to the |
In Ruby a
Same for
|
I'm +1 for this but let's use Rails AR's message: |
@@ -1645,6 +1646,11 @@ protected static function get_models_from_cache(array $pks) | |||
*/ | |||
public static function find_by_pk($values, $options) | |||
{ | |||
if(is_null($values)) | |||
{ | |||
throw new RecordNotFound("Invalid primary key used (".var_export($values, true).")"); |
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.
Using var_export
here is unnecessary, you can simple use null
because you're using is_null
for testing.
Comments addressed. |
@@ -887,7 +887,8 @@ private function update($validate=true) | |||
protected function update_cache() | |||
{ | |||
$table = static::table(); | |||
if($table->cache_individual_model){ | |||
if($table->cache_individual_model) | |||
{ |
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.
Can you revert this change? as it is not related to the actual changes. And because there are other changes pending for this part of the code.
I think it looks good. +1 |
@shmax can you squash your commits into 1? Thanks |
Squashed to 1 commit. |
👍 thanks! Who wants the honor of merging? |
|
||
if ($expected == 1) | ||
{ | ||
if (!is_array($values)) | ||
$values = array($values); | ||
|
||
throw new RecordNotFound("Couldn't find $class with ID=" . join(',',$values)); |
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.
I'm still kinda puzzled by this. $expected == 1
so no need to join
right? Only because it's converted to an array above.
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.
Good catch: why is this moved? What effect does it have?
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.
Well, this isn't my code, and I'm not aware of all the possible cases, but this seems to catch a wide variety of them. Imagine the case where an array with one item in it is passed in. Then count($values) == 1, the force to array doesn't happen, but join still works. If a single scalar value is passed in, count($values) is still 1, it gets forced to array, and the join still works.
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.
Oh, and I probably moved it because line 1678 requires an array, but the operation to guarantee an array was happening inside a logical check. It may be that the move wasn't needed, but I found it more clear to read.
Per @koenpunt, consolidated two exceptions. |
I don't think we should remove the second exception |
Oh, I see what you mean, one sec... |
Small rearrangement, re-squashed. |
if (!is_array($values)) | ||
$values = array($values); | ||
|
||
$values = join(',',$values); |
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.
Almost there, there is no need to convert values to an array if we're going to join it directly after. Or am I missing something?
if (is_array($values))
$values = join(',', $values);
sgtm |
$values = array($values); | ||
|
||
throw new RecordNotFound("Couldn't find $class with ID=" . join(',',$values)); | ||
throw new RecordNotFound("Couldn't find $class with ID=" . $values); |
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.
Final note, please use interpolation for $values
as well, instead of concatenation.
Okie-doke. At this point I have to get to work, so if there is anything else you will either need to make the change yourself, or wait until I get back. |
I think this will be just fine, thanks! |
Fix for the following issue: