Skip to content

Commit 9d492ea

Browse files
committed
fix: simplify custom fields temporary storage
Use spl_object_id for temp storage key to avoid key mismatch during model save lifecycle
1 parent 09a35a5 commit 9d492ea

File tree

1 file changed

+11
-58
lines changed

1 file changed

+11
-58
lines changed

src/Models/Concerns/UsesCustomFields.php

Lines changed: 11 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -36,76 +36,29 @@ public function __construct($attributes = [])
3636
}
3737

3838
/**
39-
* @var array<string, array<string, mixed>>
39+
* @var array<int, array<string, mixed>>
4040
*/
4141
protected static array $tempCustomFields = [];
4242

43-
/**
44-
* Generate a unique key for storing temporary custom fields data.
45-
*/
46-
protected function getTempCustomFieldsKey(): string
47-
{
48-
// Use class name + key for existing models, or object ID for new models
49-
if ($this->exists) {
50-
return static::class.':'.$this->getKey();
51-
}
52-
53-
return static::class.':new:'.spl_object_id($this);
54-
}
55-
5643
protected static function bootUsesCustomFields(): void
5744
{
5845
static::saving(function (Model $model): void {
5946
$model->handleCustomFields();
6047
});
61-
}
62-
63-
/**
64-
* Override save to handle custom fields after saving.
65-
*/
66-
public function save(array $options = []): bool
67-
{
68-
$result = parent::save($options);
6948

70-
if ($result) {
71-
$this->saveCustomFieldsFromTemp();
72-
}
73-
74-
return $result;
75-
}
76-
77-
/**
78-
* Mutator to intercept custom_fields attribute and store it temporarily.
79-
*
80-
* @param array<string, mixed>|null $value
81-
*/
82-
public function setCustomFieldsAttribute(?array $value): void
83-
{
84-
// Handle null value (when custom_fields is not provided)
85-
if ($value === null) {
86-
return;
87-
}
88-
89-
// Store in temporary storage instead of attributes
90-
$key = $this->getTempCustomFieldsKey();
91-
self::$tempCustomFields[$key] = $value;
92-
93-
// Mark the model as dirty by updating the updated_at timestamp
94-
// This ensures the model will be saved even if no other attributes changed
95-
if ($this->usesTimestamps() && ! $this->isDirty('updated_at')) {
96-
$this->updated_at = $this->freshTimestamp();
97-
}
49+
static::saved(function (Model $model): void {
50+
$model->saveCustomFieldsFromTemp();
51+
});
9852
}
9953

10054
/**
10155
* Handle the custom fields before saving the model.
10256
*/
10357
protected function handleCustomFields(): void
10458
{
105-
if (isset($this->attributes['custom_fields']) && is_array($this->attributes['custom_fields'])) {
106-
$key = $this->getTempCustomFieldsKey();
107-
self::$tempCustomFields[$key] = $this->attributes['custom_fields'];
108-
unset($this->attributes['custom_fields']);
59+
if (isset($this->custom_fields) && is_array($this->custom_fields)) {
60+
self::$tempCustomFields[spl_object_id($this)] = $this->custom_fields;
61+
unset($this->custom_fields);
10962
}
11063
}
11164

@@ -114,11 +67,11 @@ protected function handleCustomFields(): void
11467
*/
11568
protected function saveCustomFieldsFromTemp(): void
11669
{
117-
$key = $this->getTempCustomFieldsKey();
70+
$objectId = spl_object_id($this);
11871

119-
if (isset(self::$tempCustomFields[$key]) && method_exists($this, 'saveCustomFields')) {
120-
$this->saveCustomFields(self::$tempCustomFields[$key]);
121-
unset(self::$tempCustomFields[$key]);
72+
if (isset(self::$tempCustomFields[$objectId]) && method_exists($this, 'saveCustomFields')) {
73+
$this->saveCustomFields(self::$tempCustomFields[$objectId]);
74+
unset(self::$tempCustomFields[$objectId]);
12275
}
12376
}
12477

0 commit comments

Comments
 (0)