Skip to content

Commit

Permalink
Merge pull request #66 from rxdrigocosta/custom-column-cast
Browse files Browse the repository at this point in the history
Fix casting with custom column name
  • Loading branch information
WendellAdriel committed Sep 22, 2023
2 parents 4da3c5c + 2949d2c commit ee20057
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/Concerns/CastValues.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Column;
use WendellAdriel\Lift\Attributes\Config;
use WendellAdriel\Lift\Support\PropertyInfo;

Expand Down Expand Up @@ -88,6 +89,26 @@ private static function buildCastableProperties(Collection $properties): void
continue;
}

$configAttribute = $property->attributes->first(fn ($attribute) => $attribute->getName() === Config::class);
if (filled($configAttribute)) {
$configAttribute = $configAttribute->newInstance();
if (filled($configAttribute->column)) {
self::$modelCastableProperties[static::class][$configAttribute->column] = $castAttribute->getArguments()[0];

continue;
}
}

$columnAttribute = $property->attributes->first(fn ($attribute) => $attribute->getName() === Column::class);
if (filled($columnAttribute)) {
$columnAttribute = $columnAttribute->newInstance();
if (filled($columnAttribute->name)) {
self::$modelCastableProperties[static::class][$columnAttribute->name] = $castAttribute->getArguments()[0];

continue;
}
}

self::$modelCastableProperties[static::class][$property->name] = $castAttribute->getArguments()[0];
}

Expand All @@ -103,6 +124,22 @@ private static function buildCastableProperties(Collection $properties): void
continue;
}

if (filled($configAttribute->column)) {
self::$modelCastableProperties[static::class][$configAttribute->column] = $configAttribute->cast;

continue;
}

$columnAttribute = $property->attributes->first(fn ($attribute) => $attribute->getName() === Column::class);
if (filled($columnAttribute)) {
$columnAttribute = $columnAttribute->newInstance();
if (filled($columnAttribute->name)) {
self::$modelCastableProperties[static::class][$columnAttribute->name] = $configAttribute->cast;

continue;
}
}

self::$modelCastableProperties[static::class][$property->name] = $configAttribute->cast;
}
}
Expand Down
43 changes: 43 additions & 0 deletions tests/Datasets/ProductColumn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Tests\Datasets;

use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Model;
use WendellAdriel\Lift\Attributes\Cast;
use WendellAdriel\Lift\Attributes\Column;
use WendellAdriel\Lift\Attributes\Config;
use WendellAdriel\Lift\Attributes\DB;
use WendellAdriel\Lift\Lift;

#[DB(table: 'products')]
class ProductColumn extends Model
{
use Lift;

public string $name;

#[Cast('float')]
#[Config(column: 'price')]
public float $product_price;

#[Cast('int')]
#[Column(name: 'random_number')]
public int $number;

#[Cast('immutable_datetime')]
public CarbonImmutable $expires_at;

#[Cast('array')]
public ?array $json_column;

protected $fillable = [
'name',
'price',
'random_number',
'expires_at',
'json_column',
];
}
20 changes: 20 additions & 0 deletions tests/Feature/CastTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
declare(strict_types=1);

use Tests\Datasets\Product;
use Tests\Datasets\ProductColumn;

it('casts values when creating model', function () {
$product = Product::castAndCreate([
Expand Down Expand Up @@ -138,3 +139,22 @@
->and($product->expires_at->format('Y-m-d H:i:s'))->toBe('2023-12-31 23:59:59')
->and($product->json_column)->toBe(['foo' => 'bar']);
});

it('casts values when retrieving model with custom columns', function () {
ProductColumn::create([
'name' => 'Product 1',
'price' => '10.99',
'random_number' => '123',
'expires_at' => '2023-12-31 23:59:59',
'json_column' => ['foo' => 'bar'],
]);

$product = Product::query()->first();

expect($product->name)->toBe('Product 1')
->and($product->price)->toBe(10.99)
->and($product->random_number)->toBe(123)
->and($product->expires_at)->toBeInstanceOf(Carbon\CarbonImmutable::class)
->and($product->expires_at->format('Y-m-d H:i:s'))->toBe('2023-12-31 23:59:59')
->and($product->json_column)->toBe(['foo' => 'bar']);
});

0 comments on commit ee20057

Please sign in to comment.