Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix extended model resolving #1949

Merged
merged 9 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 49 additions & 3 deletions packages/core/src/Base/Traits/HasModelExtending.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,71 @@
namespace Lunar\Base\Traits;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Lunar\Base\BaseModel;
use Lunar\Facades\ModelManifest;

trait HasModelExtending
{
public function newModelQuery(): Builder
{
$realClass = static::modelClass();
$concreteClass = static::modelClass();
$parentClass = get_parent_class($concreteClass);

// If they are both the same class i.e. they haven't changed
// then just call the parent method.
if ($this instanceof $realClass) {
if ($parentClass == BaseModel::class || $this instanceof $concreteClass) {
return parent::newModelQuery();
}

return $this->newEloquentBuilder(
$this->newBaseQueryBuilder()
)->setModel(new $realClass($this->toArray()));
)->setModel(
static::withoutEvents(
fn () => $this->replicateInto($concreteClass)
)
);
}

public function replicateInto($newClass)
{
$defaults = array_values(array_filter([
$this->getKeyName(),
$this->getCreatedAtColumn(),
$this->getUpdatedAtColumn(),
...$this->uniqueIds(),
'laravel_through_key',
]));

$attributes = Arr::except(
$this->getAttributes(), $defaults
);

return tap(new $newClass, function ($instance) use ($attributes): Model {
$instance->setRawAttributes($attributes);

$instance->setRelations($this->relations);

return $instance;
});
}

public function getForeignKey(): string
{
$parentClass = get_parent_class($this);

return $parentClass == BaseModel::class ? parent::getForeignKey() : Str::snake(class_basename($parentClass)).'_'.$this->getKeyName();

}

public function getTable()
{
$parentClass = get_parent_class($this);

return $parentClass == BaseModel::class ? parent::getTable() : (new $parentClass)->table;
}

public static function __callStatic($method, $parameters)
Expand Down
5 changes: 5 additions & 0 deletions tests/core/Stubs/Models/CustomOrder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace Lunar\Tests\Core\Stubs\Models;

class CustomOrder extends \Lunar\Models\Order {}
5 changes: 5 additions & 0 deletions tests/core/Stubs/Models/Order.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace Lunar\Tests\Core\Stubs\Models;

class Order extends \Lunar\Models\Order {}
10 changes: 8 additions & 2 deletions tests/core/Unit/Actions/Carts/CreateOrderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
use Lunar\Models\TaxClass;
use Lunar\Models\TaxRateAmount;

use function Pest\Laravel\{assertDatabaseHas};

uses(\Illuminate\Foundation\Testing\RefreshDatabase::class);

it('cant create order if already has complete and multiple disabled', function () {
Expand Down Expand Up @@ -107,6 +109,10 @@ function can_update_draft_order()
}

test('can create order', function () {
\Lunar\Facades\ModelManifest::replace(
\Lunar\Models\Contracts\Order::class,
\Lunar\Tests\Core\Stubs\Models\CustomOrder::class
);
CustomerGroup::factory()->create([
'default' => true,
]);
Expand Down Expand Up @@ -223,8 +229,8 @@ function can_update_draft_order()
->and($order->shippingAddress)->toBeInstanceOf(OrderAddress::class)
->and($order->billingAddress)->toBeInstanceOf(OrderAddress::class);

$this->assertDatabaseHas((new Order)->getTable(), $datacheck);
$this->assertDatabaseHas((new OrderLine)->getTable(), [
assertDatabaseHas((new Order)->getTable(), $datacheck);
assertDatabaseHas((new OrderLine)->getTable(), [
'identifier' => $shippingOption->getIdentifier(),
]);

Expand Down
7 changes: 7 additions & 0 deletions tests/core/Unit/Base/Traits/HasModelExtendingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ function () {
expect($sizeOption->sizes)->toHaveCount(1);
});

test('extended model returns correct table name', function () {
expect((new \Lunar\Tests\Core\Stubs\Models\CustomOrder)->getTable())
->toBe(
(new \Lunar\Models\Order)->getTable()
);
});

test('can forward static method calls to extended model', function () {
/** @see \Lunar\Tests\Core\Stubs\Models\ProductOption::getSizesStatic() */
$newStaticMethod = ProductOption::getSizesStatic();
Expand Down
Loading