mirror of
https://github.com/archtechx/virtualcolumn.git
synced 2025-12-12 23:14:04 +00:00
Throw exception if a user is trying to overwrite the data without first loading it
This commit is contained in:
parent
9cda7d498c
commit
5426e41a5c
2 changed files with 25 additions and 2 deletions
|
|
@ -31,9 +31,11 @@ trait VirtualColumn
|
||||||
*/
|
*/
|
||||||
public bool $dataEncoded = false;
|
public bool $dataEncoded = false;
|
||||||
|
|
||||||
|
public bool $dataNotLoaded = false;
|
||||||
|
|
||||||
protected function decodeVirtualColumn(): void
|
protected function decodeVirtualColumn(): void
|
||||||
{
|
{
|
||||||
if (! $this->dataEncoded) {
|
if (! $this->dataEncoded || ! $this->dataNotLoaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,6 +67,10 @@ trait VirtualColumn
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->dataNotLoaded) {
|
||||||
|
throw new \Exception('Data column was not loaded from the database. Make sure the data column is selected in the query.');
|
||||||
|
}
|
||||||
|
|
||||||
$dataColumn = static::getDataColumn();
|
$dataColumn = static::getDataColumn();
|
||||||
$customColumns = static::getCustomColumns();
|
$customColumns = static::getCustomColumns();
|
||||||
$attributes = array_filter($this->getAttributes(), fn ($key) => ! in_array($key, $customColumns), ARRAY_FILTER_USE_KEY);
|
$attributes = array_filter($this->getAttributes(), fn ($key) => ! in_array($key, $customColumns), ARRAY_FILTER_USE_KEY);
|
||||||
|
|
@ -107,11 +113,14 @@ trait VirtualColumn
|
||||||
return [
|
return [
|
||||||
'retrieved' => [
|
'retrieved' => [
|
||||||
function () {
|
function () {
|
||||||
|
// If the data column wasn't retrieved, don't decode it
|
||||||
if (($this->attributes[static::getDataColumn()] ?? null) === null) {
|
if (($this->attributes[static::getDataColumn()] ?? null) === null) {
|
||||||
|
$this->dataNotLoaded = true;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always decode after model retrieval
|
// Mark the data as encoded so that it doesn't get encoded again
|
||||||
$this->dataEncoded = true;
|
$this->dataEncoded = true;
|
||||||
|
|
||||||
$this->decodeVirtualColumn();
|
$this->decodeVirtualColumn();
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,20 @@ class VirtualColumnTest extends TestCase
|
||||||
$this->assertSame($encodedBar->bar, 'bar');
|
$this->assertSame($encodedBar->bar, 'bar');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function model_doesnt_overwrite_when_selectively_fetching() {
|
||||||
|
$this->expectExceptionMessage('Data column was not loaded from the database. Make sure the data column is selected in the query.');
|
||||||
|
|
||||||
|
FooModel::create([
|
||||||
|
'id' => 1,
|
||||||
|
'foo' => 'bar'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$foo = FooModel::query()->first(['id']);
|
||||||
|
$foo->bar = 'baz';
|
||||||
|
$foo->save();
|
||||||
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function decoding_works_with_strict_mode_enabled() {
|
public function decoding_works_with_strict_mode_enabled() {
|
||||||
FooModel::shouldBeStrict();
|
FooModel::shouldBeStrict();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue