Skip to content

Commit

Permalink
feat: add support to morph one or many addresses
Browse files Browse the repository at this point in the history
Signed-off-by: Fery Wardiyanto <ferywardiyanto@gmail.com>
  • Loading branch information
feryardiant committed Jul 4, 2023
1 parent 46b44bb commit b75e394
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 11 deletions.
9 changes: 7 additions & 2 deletions database/migrations/create_nusa_tables.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ public function up(): void
$table->timestamps();
});

Schema::create('has_addresses', function (Blueprint $table) {
Schema::create('has_one_addresses', function (Blueprint $table) {
$table->id();
});

Schema::create('has_many_addresses', function (Blueprint $table) {
$table->id();
});
}
Expand All @@ -91,7 +95,8 @@ public function down(): void
{
$tableNames = config('creasi.nusa.table_names');

Schema::dropIfExists('has_addresses');
Schema::dropIfExists('has_many_addresses');
Schema::dropIfExists('has_one_addresses');
Schema::dropIfExists('address');
Schema::dropIfExists($tableNames['villages']);
Schema::dropIfExists($tableNames['districts']);
Expand Down
Binary file modified database/nusa.sqlite
Binary file not shown.
30 changes: 30 additions & 0 deletions src/Models/Address.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Illuminate\Database\Eloquent\Model as EloquentModel;

/**
* @property-read ?EloquentModel $owner
* @property-read ?Province $province
* @property-read ?Regency $regency
* @property-read ?District $district
Expand Down Expand Up @@ -40,6 +41,35 @@ public function getFillable()
]);
}

public function associateWith(
Village $village,
?District $district = null,
?Regency $regency = null,
?Province $province = null,
) {
$this->village()->associate($village);

if (! $district) {
$district = $village->district;
}

$this->district()->associate($district);

if (! $regency) {
$regency = $village->regency;
}

$this->regency()->associate($regency);

if (! $province) {
$province = $village->province;
}

$this->province()->associate($province);

return $this->fresh();
}

/**
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
*/
Expand Down
19 changes: 19 additions & 0 deletions src/Support/HasAddress.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Creasi\Nusa\Support;

/**
* @mixin \Illuminate\Database\Eloquent\Model
*/
trait HasAddress
{
/**
* @return \Illuminate\Database\Eloquent\Relations\MorphOne|\Creasi\Nusa\Contracts\Address
*/
public function address()
{
return $this->morphOne(\config('creasi.nusa.addressable'), 'owner');
}
}
2 changes: 1 addition & 1 deletion tests/HasAddress.php → tests/HasManyAddresses.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Creasi\Nusa\Support\HasAddresses;
use Illuminate\Database\Eloquent\Model;

class HasAddress extends Model
class HasManyAddresses extends Model
{
use HasAddresses;

Expand Down
15 changes: 15 additions & 0 deletions tests/HasOneAddress.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Creasi\Tests;

use Creasi\Nusa\Support\HasAddress;
use Illuminate\Database\Eloquent\Model;

class HasOneAddress extends Model
{
use HasAddress;

public $timestamps = false;
}
37 changes: 29 additions & 8 deletions tests/NusaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Creasi\Tests\Models\ProvinceTest;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Collection;
use PHPUnit\Framework\Attributes\Depends;
use PHPUnit\Framework\Attributes\DependsExternal;
use PHPUnit\Framework\Attributes\Test;

Expand All @@ -32,17 +33,37 @@ public function it_may_accociate_with_address(Collection $villages)

$address->save();

$addressOwner = new HasAddress();
$address->associateWith($village);

$addressOwner->save();
$this->assertSame($village->province, $address->province);
$this->assertNull($address->owner);

$address->owner()->associate($addressOwner);
return $address->fresh();
}

#[Test]
#[Depends('it_may_accociate_with_address')]
public function may_has_many_addresses(Address $address)
{
$owner = new HasManyAddresses();

$owner->save();

$owner->addresses()->save($address);

$this->assertCount(1, $owner->addresses);
}

#[Test]
#[Depends('it_may_accociate_with_address')]
public function may_has_one_address(Address $address)
{
$owner = new HasOneAddress();

$owner->save();

$address->province()->associate($village->province);
$address->regency()->associate($village->regency);
$address->district()->associate($village->district);
$address->village()->associate($village);
$owner->address()->save($address);

$this->assertCount(1, $addressOwner->addresses);
$this->assertInstanceOf(Address::class, $owner->address);
}
}

0 comments on commit b75e394

Please sign in to comment.