Skip to content
Closed
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
23 changes: 23 additions & 0 deletions src/Model/Concerns/HasUuids.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,27 @@ public function getIncrementing()

return $this->incrementing;
}

/**
* Initialize the model with unique identifiers.
*
* @param array $columns
* @return void
*/
protected function initialize(array $columns): void
{
foreach ($columns as $column) {
if (in_array($column, $this->uniqueIds()) && ! $this->{$column}) {
Comment on lines +75 to +76
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

Inside initialize(), the in_array($column, $this->uniqueIds()) check is redundant when the caller already passes $this->uniqueIds(), and it also recomputes uniqueIds() on every iteration. Consider either removing the membership check entirely or computing uniqueIds() once before the loop.

Suggested change
foreach ($columns as $column) {
if (in_array($column, $this->uniqueIds()) && ! $this->{$column}) {
$uniqueIds = $this->uniqueIds();
foreach ($columns as $column) {
if (in_array($column, $uniqueIds, true) && ! $this->{$column}) {

Copilot uses AI. Check for mistakes.
$this->{$column} = $this->newUniqueId();
}
}
}
Comment on lines +73 to +80
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

The helper method name initialize is very generic and can easily collide with other traits or model methods, and it is also easy to confuse with the model’s trait initializer convention (initialize{TraitName} collected in Model::bootTraits). Renaming this to something UUID-specific (e.g., initializeUniqueIds / setUniqueIdsIfMissing) will reduce the risk of trait method collisions and improve readability.

Copilot uses AI. Check for mistakes.

public function save(array $options = []): bool
{
$this->initialize($this->uniqueIds());
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

Overriding save() to assign UUIDs unconditionally can mutate primary keys (or other uniqueIds) during update operations. In particular, if an existing model instance has a falsey/missing key attribute (e.g., loaded with a select that omits the PK), this will generate a new UUID and the subsequent update can target the wrong row (or no row) while still returning true. Consider only generating IDs for inserts (e.g., guard with if (! $this->exists)), or move the logic to the insert path (such as performInsert) so updates never auto-regenerate identifiers.

Suggested change
$this->initialize($this->uniqueIds());
if (! $this->exists) {
$this->initialize($this->uniqueIds());
}

Copilot uses AI. Check for mistakes.

return parent::save($options);
Comment on lines +82 to +86
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

This change alters persistence behavior by auto-populating UUID columns during save(), but there are no tests covering the new behavior. Please add/update tests to assert (1) a new model gets a UUID assigned before insert, and (2) saving an existing model does not regenerate or change its UUID/primary key.

Copilot uses AI. Check for mistakes.
}
}

Loading