Skip to content

Commit

Permalink
improved eloquent integration with dirty tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
cappuc committed Dec 6, 2022
1 parent 204a150 commit 6a2b8b3
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 10 deletions.
8 changes: 4 additions & 4 deletions config/temporal.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@
'deserialize_attribute_case' => null,

/**
* If true adds a `__exists` attribute to the serialized model
* which indicate that the model is saved to database and it is used on deserialization when creating the model.
* If false (or `__exists` is not present) the model will be created as existing model if primary key is present.
* If true adds additional metadata fields (`__exists`, `__dirty`) to the serialized model to improve deserialization.
* `__exists`: indicate that the model is saved to database.
* `__dirty`: indicate that the model has unsaved changes. (original values are not included in the serialized payload but the deserialized model will be marked as dirty)
*/
'include_exists_field' => false,
'include_metadata_field' => false,
],
],
];
36 changes: 30 additions & 6 deletions src/Integrations/Eloquent/TemporalEloquentSerialize.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ public function toTemporalPayload(): array
return Collection::make($this->attributesToArray())
->merge($relations)
->mapWithKeys(fn (mixed $value, string $key) => [$this->mapAttributeKeyToTemporal($key) => $value])
->put('__exists', $this->exists)
->when(config('temporal.integrations.eloquent.include_metadata_field', false), fn (Collection $collection) => $collection
->put('__exists', $this->exists)
->put('__dirty', $this->isDirty())
)
->all();
}

Expand All @@ -72,10 +75,19 @@ public static function fromTemporalPayload(array $payload): static
default => [],
});

$instance = $model->newInstance(
$attributes->except($relationships->keys()->merge(['__exists']))->all(),
$attributes->get('__exists', $attributes->get($model->getKeyName()) !== null),
);
/** @var bool $exists */
$exists = $attributes->get('__exists', $attributes->get($model->getKeyName()) !== null);

/** @var bool $dirty */
$dirty = $attributes->get('__dirty', true);

$instance = $model->newInstance([], $exists);

$instance->forceFill($attributes->except($relationships->keys()->merge(['__exists', '__dirty']))->all());

if (! $dirty) {
$instance->syncOriginal();
}

foreach ($relationships as $attributeKey => $relationship) {
/** @var Relation $relation */
Expand Down Expand Up @@ -114,8 +126,20 @@ private static function buildRelatedInstance(Model $relatedModel, ?array $attrib
return $relatedModel::fromTemporalPayload($attributes);
}

/** @var bool $exists */
$exists = Arr::get($attributes, '__exists', Arr::get($attributes, $relatedModel->getKeyName()) !== null);

return $relatedModel->newInstance(Arr::except($attributes, ['__exists']), $exists);
/** @var bool $dirty */
$dirty = Arr::get($attributes, '__dirty', true);

$relatedModelInstance = $relatedModel->newInstance([], $exists);

$relatedModelInstance->forceFill(Arr::except($attributes, ['__exists', '__dirty']));

if ($dirty) {
$relatedModelInstance->syncOriginal();
}

return $relatedModelInstance;
}
}

0 comments on commit 6a2b8b3

Please sign in to comment.