From dda54ddab08dab244e9dc091ce7a4d5fc732f607 Mon Sep 17 00:00:00 2001 From: Henrique Felix Date: Mon, 12 May 2025 17:23:27 +0000 Subject: [PATCH] feat: Add new column for "foo_child" table to link with the table "foo". - Add to Virtual Column a new rule to prevent store relationships names in the "data" column. --- src/VirtualColumn.php | 9 +++++ tests/VirtualColumnTest.php | 33 +++++++++++++++++++ ...3_10_21_000001_create_foo_childs_table.php | 2 ++ 3 files changed, 44 insertions(+) diff --git a/src/VirtualColumn.php b/src/VirtualColumn.php index 768a07f..ad27109 100644 --- a/src/VirtualColumn.php +++ b/src/VirtualColumn.php @@ -76,6 +76,15 @@ trait VirtualColumn // Remove attribute from the model unset($this->attributes[$key]); unset($this->original[$key]); + + // Check if the attribute is a method on the model + $myKeyIsAnFunction = method_exists($this, $key); + + // If the attribute is a method, remove it from the attributes array + // This is to prevent the attribute from being added to the data column + if ($myKeyIsAnFunction) { + unset($attributes[$key]); + } } // Add attribute to the data column diff --git a/tests/VirtualColumnTest.php b/tests/VirtualColumnTest.php index 9808ad7..d153d58 100644 --- a/tests/VirtualColumnTest.php +++ b/tests/VirtualColumnTest.php @@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Crypt; use Illuminate\Database\Eloquent\Model; use Stancl\VirtualColumn\VirtualColumn; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; +use Illuminate\Database\Eloquent\Relations\HasMany; class VirtualColumnTest extends TestCase { @@ -162,6 +163,32 @@ class VirtualColumnTest extends TestCase // Reset static property MyModel::$customEncryptedCastables = []; } + + /** @test */ + public function test_try_save_property_same_name_as_function() { + + /** @var FooModel $model */ + $model = FooModel::create([ + 'custom1' => "bar", + 'custom2' => 'ool', + 'childrens' => [ // children are the name of the relation with FooChild + 'custom' => 'abc' + ] + ]); + + // After save, we should ignore the relationship as parameter + // To not throw an exception when trying to access the relation. + $this->assertTrue($model->childrens instanceof \Illuminate\Database\Eloquent\Collection); + $this->assertTrue($model->childrens() instanceof \Illuminate\Database\Eloquent\Relations\HasMany); + + $model->childrens()->create([ + 'foo' => 'test' + ]); + + // Double check after add a real foo child. + // Check if we dont get the error to call a eloquent method in array. + $this->assertTrue($model->childrens()->first() instanceof FooChild); + } } class ParentModel extends Model @@ -200,6 +227,11 @@ class FooModel extends ParentModel { return 'virtual'; } + + public function childrens(): HasMany + { + return $this->hasMany(FooChild::class, 'foo_id'); + } } class EncryptedCast implements CastsAttributes @@ -223,6 +255,7 @@ class FooChild extends ParentModel { return [ 'id', + 'foo_id', 'foo', ]; } diff --git a/tests/etc/migrations/2023_10_21_000001_create_foo_childs_table.php b/tests/etc/migrations/2023_10_21_000001_create_foo_childs_table.php index bb39d10..25ea165 100644 --- a/tests/etc/migrations/2023_10_21_000001_create_foo_childs_table.php +++ b/tests/etc/migrations/2023_10_21_000001_create_foo_childs_table.php @@ -18,6 +18,8 @@ class CreateFooChildsTable extends Migration Schema::create('foo_childs', function (Blueprint $table) { $table->increments('id'); + $table->unsignedInteger('foo_id')->nullable(); + $table->string('foo')->nullable(); $table->json('data')->nullable();