Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
BaseActiveRecord::find() has inconsistent return types #2999
Any call to find() which includes an attribute, such as
The issue is that the if blocks use
return $query->where([$primaryKey => $q])->one();
otherwise the function returns the ActiveQuery object created at the start of the function body:
$query = static::createQuery(); ... return $query;
This creates inconsistent behaviour (using ->find() to get an object versus ->find() to start a query) and prevents extending your query or adding relations as such:
Faces::find(['type' => 'frown'])->with('eyes')->one();
Although ->where() exists to narrow down attributes, it is confusing to have both find() and where() doing the job.
Two ideas to fix:
I think my main complaint is that find() and where() have the same functionality, but using find() like where() has different results than other uses of find(). This can lead to confusion.
find() by itself acts like the start of a query builder (like select() or similar functions in other ORMs), but find(...) becomes an finalized query. To me, a function can accept varying parameters but should have the same RESULT. So, to reiterate and expand upon the suggestions above:
I feel like option 3 makes things the most consistent. It will break existing code, but in a way that keeps calls consistent.
// replaces Faces::find(5); Faces::find()->pk(5)->one(); // replaces Faces::find()->where(['must_know_your_pk' => 5])->with('eyes')->one(); // (find(5)->with() was not possible) Faces::find()->pk(5)->with('eyes')->one(); // existing functionality already covers Faces::find(['type' => 'frown'); // also covers find([...])->with() call which was not possible) Faces::find()->where(['type' => 'frown'])->one(); Faces::find()->where(['type' => 'frown'])->with('eyes')->one();
Method names should be unique and descriptive to avoid confusion, especially among newcomers to Yii and those transitioning from Yii1. Re-using one() and all() with different functionality is confusing.
I still believe option 3 above is the best (
My 5 cents. 1st example is more preferable for me. And also, no problem with current syntax, it's short and clear. For me is better to add