Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Bug #558: Fix `SoftDelete` with initiated custom date (@Tigrov)
- Enh #564: Clarify `$relations` parameter type in `JoinWith::__construct()` from `array<string|Closure>` to
`array<string|callable(ActiveQueryInterface):void>` (@vjik)
- Bug #562: Fix `ActiveRecordInterface::upsert()` to prioritize passed associative values during updates (@Tigrov)
- Bug #561: Fix `ActiveRecordInterface::upsert()` with `$updateProperties = false` (@Tigrov)
- Bug #550: Relation query should be created by related class, not primary model class (@batyrmastyr)

Expand Down
5 changes: 1 addition & 4 deletions src/ActiveRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,7 @@ protected function upsertInternal(?array $insertProperties = null, array|bool $u
$updateNames = array_filter($updateProperties, is_int(...), ARRAY_FILTER_USE_KEY);

if (!empty($updateNames)) {
$updateProperties = array_merge(
array_diff_key($updateProperties, $updateNames),
$this->newPropertyValues($updateNames),
);
$updateProperties = array_diff_key($updateProperties, $updateNames) + $this->newValues($updateNames);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but perhaps #559 is not a bug. To avoid potential problems, we need to give priority to passed properties with values.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is OK. But I suggest don't close issue.

}
/** @psalm-var array<string, mixed> $updateProperties */

Expand Down
6 changes: 4 additions & 2 deletions src/ActiveRecordInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -697,10 +697,12 @@ public function updateAll(array $propertyValues, array|string $condition = [], a
* ```
*
* @param array|null $insertProperties List of property names or name-values pairs that need to be inserted.
* If name-value pairs are specified, the values will be used for insertion.
* Defaults to `null`, meaning all changed property values will be inserted.
* @param array|bool $updateProperties List of property names or name-values pairs that need to be updated
* if the record already exists. Also available a boolean value:
* - `true` the record values will be updated to match the insert property values;
* if the record already exists. If name-value pairs are specified, the values will be used for update.
* Also available a boolean value:
* - `true` the record values will be updated to match the inserted property values;
* - `false` no update will be performed if the record already exist.
*
* @throws InvalidConfigException
Expand Down
9 changes: 6 additions & 3 deletions src/Event/BeforeUpsert.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ final class BeforeUpsert extends AbstractEvent
{
/**
* @param ActiveRecordInterface $model The model being upserted.
* @param array|null $insertProperties Properties to be inserted. If null, the properties will be taken from the model.
* @param array|bool $updateProperties Properties to be updated. If false, no properties will be updated.
* If true, `$insertProperties` will be used for update as well.
* @param array|null $insertProperties List of property names or name-values pairs that need to be inserted.
* If name-value pairs are specified, the values will be used for insertion.
* If `null`, the properties will be taken from the model.
* @param array|bool $updateProperties List of property names or name-values pairs that need to be updated
* if the record already exists. If name-value pairs are specified, the values will be used for update.
* If `true`, `$insertProperties` will be used for update as well. If `false`, no properties will be updated.
*/
public function __construct(
ActiveRecordInterface $model,
Expand Down
2 changes: 1 addition & 1 deletion tests/ActiveRecordTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,7 @@ public static function dataUpsert(): array
'expected' => [
'id' => 3,
'email' => 'user3@example.com',
'address' => 'insert address',
'address' => 'update address',
],
],
];
Expand Down
Loading