Skip to content

Commit 81d427d

Browse files
authored
Make ActiveRecordInterface::query() method static (#442)
1 parent 1092329 commit 81d427d

33 files changed

Lines changed: 373 additions & 396 deletions

docs/create-model.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,7 @@ Now you can use `$user->getProfile()` and `$user->getOrders()` to access the rel
274274
```php
275275
use Yiisoft\ActiveRecord\ActiveQuery;
276276

277-
$userQuery = new ActiveQuery(User::class);
278-
279-
$user = $userQuery->where(['id' => 1])->one();
277+
$user = User::query()->where(['id' => 1])->one();
280278

281279
$profile = $user->getProfile();
282280
$orders = $user->getOrders();

docs/define-relations.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -402,9 +402,7 @@ To do this, use the `ActiveQueryInterface::with()` method.
402402
```php
403403
use Yiisoft\ActiveRecord\ActiveQuery;
404404

405-
$userQuery = new ActiveQuery(User::class);
406-
407-
$users = $userQuery->with('profile', 'orders')->all();
405+
$users = User::query()->with('profile', 'orders')->all();
408406
```
409407

410408
In the example, `profile` and `orders` are the relation names that you want to load in advance.
@@ -451,9 +449,7 @@ Now you can use `$user->getProfile()` and `$user->getOrders()` to access the rel
451449
```php
452450
use Yiisoft\ActiveRecord\ActiveQuery;
453451

454-
$userQuery = (new ActiveQuery(User::class))->where(['id' => 1]);
455-
456-
$user = $userQuery->one();
452+
$user = User::query()->where(['id' => 1])->one();
457453

458454
$profile = $user->getProfile();
459455
$orders = $user->getOrders();

docs/optimistic-locking.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ final class DocumentController
114114
): ResponseInterface {
115115
$id = (int) $request->getAttribute('id');
116116

117-
$document = (new ActiveQuery(Document::class))->findByPk($id);
117+
$document = Document::query()->findByPk($id);
118118

119119
if ($document === null) {
120120
throw new NotFoundException('Document not found.');
@@ -129,7 +129,7 @@ final class DocumentController
129129
$data = $request->getParsedBody();
130130

131131
$id = (int) $data['id'];
132-
$document = (new ActiveQuery(Document::class))->findByPk($id);
132+
$document = Document::query()->findByPk($id);
133133

134134
if ($document === null) {
135135
throw new NotFoundException('Document not found.');

src/AbstractActiveRecord.php

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ abstract protected function upsertInternal(
9898
array|bool $updateProperties = true,
9999
): bool;
100100

101+
public function createQuery(ActiveRecordInterface|Closure|null|string $modelClass = null): ActiveQueryInterface
102+
{
103+
return static::query($modelClass);
104+
}
105+
101106
public function delete(): int
102107
{
103108
return $this->deleteInternal();
@@ -363,18 +368,6 @@ public function insert(array|null $properties = null): bool
363368
return $this->insertInternal($properties);
364369
}
365370

366-
/**
367-
* @param ActiveRecordInterface|Closure|string|null $modelClass The class name of the related record, or an instance of
368-
* the related record, or a Closure to create an {@see ActiveRecordInterface} object. If `null`, the current model
369-
* will be used.
370-
*
371-
* @psalm-param ModelClass $modelClass
372-
*/
373-
public function query(ActiveRecordInterface|Closure|null|string $modelClass = null): ActiveQueryInterface
374-
{
375-
return new ActiveQuery($modelClass ?? $this);
376-
}
377-
378371
public function isChanged(): bool
379372
{
380373
return !empty($this->newValues());
@@ -564,6 +557,11 @@ public function populateRelation(string $name, array|ActiveRecordInterface|null
564557
$this->related[$name] = $records;
565558
}
566559

560+
public static function query(ActiveRecordInterface|Closure|null|string $modelClass = null): ActiveQueryInterface
561+
{
562+
return new ActiveQuery($modelClass ?? static::class);
563+
}
564+
567565
/**
568566
* Repopulates this active record with the latest data.
569567
*
@@ -572,7 +570,7 @@ public function populateRelation(string $name, array|ActiveRecordInterface|null
572570
*/
573571
public function refresh(): bool
574572
{
575-
$record = $this->query()->findByPk($this->primaryKeyOldValues());
573+
$record = $this->createQuery()->findByPk($this->primaryKeyOldValues());
576574

577575
return $this->refreshInternal($record);
578576
}
@@ -1050,7 +1048,7 @@ protected function createRelationQuery(
10501048
array $link,
10511049
bool $multiple,
10521050
): ActiveQueryInterface {
1053-
return $this->query($modelClass)->primaryModel($this)->link($link)->multiple($multiple);
1051+
return $this->createQuery($modelClass)->primaryModel($this)->link($link)->multiple($multiple);
10541052
}
10551053

10561054
/**

src/ActiveQuery.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
* These options can be configured using methods of the same name. For example:
7878
*
7979
* ```php
80-
* $customerQuery = new ActiveQuery(Customer::class);
80+
* $customerQuery = Customer::query();
8181
* $query = $customerQuery->with('orders')->asArray()->all();
8282
* ```
8383
*

src/ActiveQueryInterface.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public function asArray(bool|null $value = true): static;
6262
*
6363
* ```php
6464
* // Create active query
65-
* CustomerQuery = new ActiveQuery(Customer::class);
65+
* CustomerQuery = Customer::query();
6666
* // find customers together with their orders and country
6767
* CustomerQuery->with('orders', 'country')->all();
6868
* // find customers together with their orders and the orders' shipping address
@@ -151,19 +151,19 @@ public function buildJoinWith(): void;
151151
*
152152
* ```php
153153
* // Find all orders that contain books, and eager loading "books".
154-
* $orderQuery = new ActiveQuery(Order::class);
154+
* $orderQuery = Order::query();
155155
* $orderQuery->joinWith('books', true, 'INNER JOIN')->all();
156156
*
157157
* // Find all orders, eagerly load "books", and sort the orders and books by the book names.
158-
* $orderQuery = new ActiveQuery(Order::class, $db);
158+
* $orderQuery = Order::query();
159159
* $orderQuery->joinWith([
160160
* 'books' => function (ActiveQuery $query) {
161161
* $query->orderBy('item.name');
162162
* }
163163
* ])->all();
164164
*
165165
* // Find all orders that contain books of the category 'Science fiction', using the alias "b" for the book table.
166-
* $order = new ActiveQuery(Order::class, $db);
166+
* $order = Order::query();
167167
* $orderQuery->joinWith(['books b'], true, 'INNER JOIN')->where(['b.category' => 'Science fiction'])->all();
168168
* ```
169169
* @param array|bool $eagerLoading Whether to eager load the relations specified in `$with`. When this is boolean.
@@ -353,7 +353,7 @@ public function relatedRecords(): ActiveRecordInterface|array|null;
353353
* In the examples below, the `id` column is the primary key of the table.
354354
*
355355
* ```php
356-
* $customerQuery = new ActiveQuery(Customer::class);
356+
* $customerQuery = Customer::query();
357357
*
358358
* $customer = $customerQuery->findByPk(1); // WHERE id = 1
359359
* ```
@@ -365,7 +365,7 @@ public function relatedRecords(): ActiveRecordInterface|array|null;
365365
* In the examples below, the `id` and `id2` columns are the composite primary key of the table.
366366
*
367367
* ```php
368-
* $orderItemQuery = new ActiveQuery(OrderItem::class);
368+
* $orderItemQuery = OrderItem::query();
369369
*
370370
* $orderItem = $orderItemQuery->findByPk([1, 2]); // WHERE id = 1 AND id2 = 2
371371
* ```
@@ -378,7 +378,7 @@ public function relatedRecords(): ActiveRecordInterface|array|null;
378378
* {
379379
* $id = (string) $request->getAttribute('id');
380380
*
381-
* $customerQuery = new ActiveQuery(Customer::class);
381+
* $customerQuery = Customer::query();
382382
* $customer = $customerQuery->findByPk($id);
383383
* }
384384
* ```

src/ActiveQueryTrait.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,12 @@ public function asArray(bool|null $value = true): static
4949
* The following are some usage examples:
5050
*
5151
* ```php
52-
* // Create active query
53-
* CustomerQuery = new ActiveQuery(Customer::class);
5452
* // find customers together with their orders and country
55-
* CustomerQuery->with('orders', 'country')->all();
53+
* Customer::query()->with('orders', 'country')->all();
5654
* // find customers together with their orders and the orders' shipping address
57-
* CustomerQuery->with('orders.address')->all();
55+
* Customer::query()->with('orders.address')->all();
5856
* // find customers together with their country and orders of status 1
59-
* CustomerQuery->with([
57+
* Customer::query()->with([
6058
* 'orders' => function (ActiveQuery $query) {
6159
* $query->andWhere('status = 1');
6260
* },
@@ -69,8 +67,8 @@ public function asArray(bool|null $value = true): static
6967
* For example, the following two statements are equivalent:
7068
*
7169
* ```php
72-
* CustomerQuery->with('orders', 'country')->all();
73-
* CustomerQuery->with('orders')->with('country')->all();
70+
* Customer::query()->with('orders', 'country')->all();
71+
* Customer::query()->with('orders')->with('country')->all();
7472
* ```
7573
*
7674
* @param array|string ...$with A list of relation names or relation definitions.

src/ActiveRecord.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@
6666
* $user->save(); // a new row is inserted into user table
6767
*
6868
* // the following will retrieve the user 'CeBe' from the database
69-
* $userQuery = new ActiveQuery(User::class);
70-
* $user = $userQuery->where(['name' => 'CeBe'])->one();
69+
* $user = User::query()->where(['name' => 'CeBe'])->one();
7170
*
7271
* // this will get related records from orders table when relation is defined
7372
* $orders = $user->orders;

src/ActiveRecordInterface.php

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Yiisoft\ActiveRecord;
66

7+
use Closure;
78
use Throwable;
89
use Yiisoft\Db\Connection\ConnectionInterface;
910
use Yiisoft\Db\Constant\ColumnType;
@@ -12,6 +13,9 @@
1213
use Yiisoft\Db\Exception\InvalidCallException;
1314
use Yiisoft\Db\Exception\InvalidConfigException;
1415

16+
/**
17+
* @psalm-import-type ModelClass from ActiveQuery
18+
*/
1519
interface ActiveRecordInterface
1620
{
1721
/**
@@ -30,6 +34,15 @@ public function propertyNames(): array;
3034
*/
3135
public function columnType(string $propertyName): string;
3236

37+
/**
38+
* @param ActiveRecordInterface|Closure|string|null $modelClass The class name of the related record, or an instance
39+
* of the related record, or a Closure to create an {@see ActiveRecordInterface} object. If `null`, the current model
40+
* will be used.
41+
*
42+
* @psalm-param ModelClass $modelClass
43+
*/
44+
public function createQuery(self|Closure|null|string $modelClass = null): ActiveQueryInterface;
45+
3346
/**
3447
* Returns the database connection used by the Active Record instance.
3548
*/
@@ -61,10 +74,9 @@ public function delete(): int;
6174
* > Warning: If you don't specify any condition, this method will delete **all** rows in the table.
6275
*
6376
* ```php
64-
* $customerQuery = new ActiveQuery(Customer::class);
65-
* $aqClasses = $customerQuery->where('status = 3')->all();
66-
* foreach ($aqClasses as $aqClass) {
67-
* $aqClass->delete();
77+
* $customers = Customer::query()->where('status = 3')->all();
78+
* foreach ($customers as $customer) {
79+
* $customer->delete();
6880
* }
6981
* ```
7082
*
@@ -308,6 +320,11 @@ public function link(string $relationName, self $linkModel, array $extraColumns
308320
*/
309321
public function populateRelation(string $name, array|self|null $records): void;
310322

323+
/**
324+
* @psalm-param ModelClass|null $modelClass
325+
*/
326+
public static function query(self|Closure|null|string $modelClass = null): ActiveQueryInterface;
327+
311328
/**
312329
* Returns the primary key name(s) for this AR class.
313330
*
@@ -422,7 +439,7 @@ public function set(string $propertyName, mixed $value): void;
422439
* For example, to update a customer record:
423440
*
424441
* ```php
425-
* $customer = (new ActiveQuery(Customer::class))->findByPk(1);
442+
* $customer = Customer::query()->findByPk(1);
426443
* $customer->name = $name;
427444
* $customer->email = $email;
428445
* $customer->update();
@@ -471,8 +488,7 @@ public function update(array|null $properties = null): int;
471488
* > Warning: If you don't specify any condition, this method will update **all** rows in the table.
472489
*
473490
* ```php
474-
* $customerQuery = new ActiveQuery(Customer::class);
475-
* $customers = $customerQuery->where('status = 2')->all();
491+
* $customers = Customer::query()->where('status = 2')->all();
476492
* foreach ($customers as $customer) {
477493
* $customer->status = 1;
478494
* $customer->update();

src/ActiveRelationTrait.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,14 @@ public function via(string $relationName, callable|null $callable = null): stati
152152
* Let's suppose customer has several orders. If only one order was loaded:
153153
*
154154
* ```php
155-
* $orderQuery = new ActiveQuery(Order::class);
156-
* $orders = $orderQuery->where(['id' => 1])->all();
155+
* $orders = Order::query()->where(['id' => 1])->all();
157156
* $customerOrders = $orders[0]->customer->orders;
158157
* ```
159158
*
160159
* variable `$customerOrders` will contain only one order. If orders was loaded like this:
161160
*
162161
* ```php
163-
* $orderQuery = new ActiveQuery(Order::class);
164-
* $orders = $orderQuery->with('customer')->where(['customer_id' => 1])->all();
162+
* $orders = Order::query()->with('customer')->where(['customer_id' => 1])->all();
165163
* $customerOrders = $orders[0]->customer->orders;
166164
* ```
167165
*

0 commit comments

Comments
 (0)