Skip to content

Commit

Permalink
Handle model deletion better to prevent FK exceptions (#1859)
Browse files Browse the repository at this point in the history
Co-authored-by: alecritson <[email protected]>
  • Loading branch information
alecritson and alecritson authored Aug 22, 2024
1 parent 7b15b0b commit 806009b
Show file tree
Hide file tree
Showing 9 changed files with 249 additions and 12 deletions.
10 changes: 5 additions & 5 deletions packages/core/src/Models/Attribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\AsCollection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Lunar\Base\BaseModel;
Expand Down Expand Up @@ -39,14 +38,15 @@ class Attribute extends BaseModel
use HasMacros;
use HasTranslations;

public static function boot()
protected static function booted(): void
{
static::deleting(function (Model $model) {
static::deleting(function (self $attribute) {
DB::beginTransaction();
DB::table(
config('lunar.database.table_prefix').'attributables'
)->where('attribute_id', '=', $model->id)->delete();
)->where('attribute_id', '=', $attribute->id)->delete();
DB::commit();
});
parent::boot();
}

/**
Expand Down
11 changes: 11 additions & 0 deletions packages/core/src/Models/Brand.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Lunar\Base\Traits\LogsActivity;
use Lunar\Base\Traits\Searchable;
use Lunar\Database\Factories\BrandFactory;
use Lunar\Facades\DB;
use Spatie\MediaLibrary\HasMedia as SpatieHasMedia;

/**
Expand Down Expand Up @@ -55,6 +56,16 @@ protected static function newFactory(): BrandFactory
return BrandFactory::new();
}

protected static function booted(): void
{
static::deleting(function (self $brand) {
DB::beginTransaction();
$brand->discounts()->detach();
$brand->collections()->detach();
DB::commit();
});
}

/**
* Return the product relationship.
*/
Expand Down
11 changes: 11 additions & 0 deletions packages/core/src/Models/TaxZone.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Support\Facades\DB;
use Lunar\Base\BaseModel;
use Lunar\Base\Traits\HasDefaultRecord;
use Lunar\Base\Traits\HasMacros;
Expand Down Expand Up @@ -37,6 +38,16 @@ protected static function booted(): void
static::created($handleDefaultFunction);

static::updated($handleDefaultFunction);

static::deleting(function (self $taxZone) {
DB::beginTransaction();
$taxZone->countries()->delete();
$taxZone->states()->delete();
$taxZone->postcodes()->delete();
$taxZone->customerGroups()->delete();
$taxZone->taxRates()->delete();
DB::commit();
});
}

/**
Expand Down
39 changes: 38 additions & 1 deletion tests/core/Unit/Models/AddressTest.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
<?php

uses(\Lunar\Tests\Core\TestCase::class);
uses(\Lunar\Tests\Core\TestCase::class)->group('models');

use Lunar\Models\Address;
use Lunar\Models\Country;
use Lunar\Models\Customer;

use function Pest\Laravel\{assertDatabaseMissing};

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

test('can make an address with minimal attributes', function () {
Expand Down Expand Up @@ -60,3 +63,37 @@
expect($address->customer)->toBeInstanceOf(Customer::class);
expect($address->country)->toBeInstanceOf(Country::class);
});

test('can delete address', function () {
$country = Country::factory()->create();
$customer = Customer::factory()->create();

$data = [
'country_id' => $country->id,
'customer_id' => $customer->id,
'first_name' => 'Tony',
'last_name' => 'Stark',
'line_one' => 'Stark Industries Headquarters',
'line_two' => 'Line Two',
'line_three' => 'Line Three',
'state' => 'Southern California',
'postcode' => 123456,
'delivery_instructions' => 'Pass on to Happy',
'contact_email' => '[email protected]',
'contact_phone' => '123123123',
'meta' => [
'door_code' => 0000,
],
'shipping_default' => true,
'billing_default' => true,
'city' => 'Los Angeles',
];

$address = Address::create($data);

$address->delete();

assertDatabaseMissing(Address::class, [
'id' => $address->id,
]);
});
30 changes: 27 additions & 3 deletions tests/core/Unit/Models/AttributeGroupTest.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<?php

uses(\Lunar\Tests\Core\TestCase::class);
uses(\Lunar\Tests\Core\TestCase::class)->group('models');

use Lunar\Models\Attribute;
use Lunar\Models\AttributeGroup;

use function Pest\Laravel\{assertDatabaseMissing};

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

test('can make a attribute group', function () {
Expand Down Expand Up @@ -31,11 +34,32 @@
'position' => 5,
]);

expect($attributeGroup->attributes)->toHaveCount(0);
expect($attributeGroup->attributes()->count())->toBe(0);

$attributeGroup->attributes()->create(
Attribute::factory()->make()->toArray()
);

expect($attributeGroup->refresh()->attributes)->toHaveCount(1);
expect($attributeGroup->refresh()->attributes()->count())->toBe(1);
});

test('can delete attribute group', function () {
$attributeGroup = AttributeGroup::factory()->create([
'attributable_type' => 'product_type',
'name' => [
'en' => 'SEO',
],
'handle' => 'seo',
'position' => 5,
]);

$attributeGroup->attributes()->create(
Attribute::factory()->make()->toArray()
);

$attributeGroup->delete();

assertDatabaseMissing(AttributeGroup::class, [
'id' => $attributeGroup->id,
]);
});
45 changes: 44 additions & 1 deletion tests/core/Unit/Models/AttributeTest.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<?php

uses(\Lunar\Tests\Core\TestCase::class);
uses(\Lunar\Tests\Core\TestCase::class)->group('models');

use Lunar\Models\Attribute;
use Lunar\Models\AttributeGroup;

use function Pest\Laravel\{assertDatabaseMissing};

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

test('can make a attribute', function () {
Expand Down Expand Up @@ -41,3 +44,43 @@
expect($attribute->position)->toEqual(4);
expect($attribute->configuration->get('options'))->toEqual($options);
});

test('can delete an attribute', function () {
$options = [
'Red',
'Blue',
'Green',
];

$attribute = Attribute::factory()
->for(AttributeGroup::factory())
->create([
'position' => 4,
'name' => [
'en' => 'Meta Description',
],
'description' => [
'en' => 'Meta Description',
],
'handle' => 'meta_description',
'section' => 'product_variant',
'type' => \Lunar\FieldTypes\Text::class,
'required' => false,
'default_value' => '',
'configuration' => [
'options' => $options,
],
'system' => true,
]);

\Illuminate\Support\Facades\DB::table('lunar_attributables')->insert([
'attributable_type' => 'Lunar\Models\ProductType',
'attributable_id' => 1,
'attribute_id' => $attribute->id,
]);

$attribute->delete();
assertDatabaseMissing(Attribute::class, [
'id' => $attribute->id,
]);
});
48 changes: 47 additions & 1 deletion tests/core/Unit/Models/BrandTest.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
<?php

uses(\Lunar\Tests\Core\TestCase::class);
uses(\Lunar\Tests\Core\TestCase::class)->group('models');

use Illuminate\Support\Facades\Config;
use Lunar\Generators\UrlGenerator;
use Lunar\Models\Brand;
use Lunar\Models\Language;
use Lunar\Models\Url;

use function Pest\Laravel\assertDatabaseHas;
use function Pest\Laravel\assertDatabaseMissing;

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

test('can make a brand', function () {
Expand Down Expand Up @@ -75,3 +79,45 @@
]);
expect($brand->mappedAttributes)->toHaveCount(1);
});

test('can delete a brand', function () {
$brand = Brand::factory()->create([
'name' => 'Test Brand',
]);

\Lunar\Models\Product::factory()->create([
'brand_id' => $brand->id,
]);

$discount = \Lunar\Models\Discount::factory()->create();
$collection = \Lunar\Models\Collection::factory()->create();

$brand->discounts()->attach($discount);
$brand->collections()->attach($collection);

assertDatabaseHas($brand->discounts()->getTable(), [
'brand_id' => $brand->id,
'discount_id' => $discount->id,
]);

assertDatabaseHas($brand->collections()->getTable(), [
'brand_id' => $brand->id,
'collection_id' => $collection->id,
]);

$brand->delete();

assertDatabaseMissing($brand->discounts()->getTable(), [
'brand_id' => $brand->id,
'discount_id' => $discount->id,
]);

assertDatabaseMissing($brand->collections()->getTable(), [
'brand_id' => $brand->id,
'collection_id' => $collection->id,
]);

assertDatabaseMissing(Brand::class, [
'id' => $brand->id,
]);
});
13 changes: 12 additions & 1 deletion tests/core/Unit/Models/ChannelTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

uses(\Lunar\Tests\Core\TestCase::class);
uses(\Lunar\Tests\Core\TestCase::class)->group('models');

use Lunar\Models\Channel;

Expand Down Expand Up @@ -51,3 +51,14 @@

expect($channel->refresh()->discounts)->toHaveCount(1);
});

test('can soft delete a channel', function () {
$channel = Channel::factory()->create();

$channel->delete();

\Pest\Laravel\assertDatabaseHas(Channel::class, [
'id' => $channel->id,
'deleted_at' => now(),
]);
});
54 changes: 54 additions & 0 deletions tests/core/Unit/Models/TaxZoneTest.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<?php

uses(\Lunar\Tests\Core\TestCase::class);

use Lunar\Models\Country;
use Lunar\Models\CustomerGroup;
use Lunar\Models\State;
use Lunar\Models\TaxZone;

use function Pest\Laravel\assertDatabaseHas;
use function Pest\Laravel\assertDatabaseMissing;

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

test('can make a tax zone class', function () {
Expand Down Expand Up @@ -121,3 +125,53 @@

expect($zone->refresh()->customerGroups)->toHaveCount(1);
});

test('can delete a tax zone', function () {
$data = [
'name' => 'L.A.',
'zone_type' => 'state',
'price_display' => 'tax_inclusive',
'active' => true,
'default' => true,
];

$zone = TaxZone::factory()->create($data);

\Pest\Laravel\assertDatabaseHas((new TaxZone)->getTable(), $data);

$country = Country::factory()->create();
$state = State::factory()->create();

expect($zone->refresh()->customerGroups)->toHaveCount(0);

$zone->customerGroups()->create([
'customer_group_id' => CustomerGroup::factory()->create()->id,
]);

expect($zone->refresh()->customerGroups)->toHaveCount(1);

$zone->countries()->create(['country_id' => $country->id]);
$zone->states()->create(['state_id' => $state->id]);
$zone->postcodes()->create([
'country_id' => $country->id,
'postcode' => 'ABC 123',
]);

\Lunar\Models\TaxRate::factory()->create([
'tax_zone_id' => $zone->id,
]);

assertDatabaseHas(\Lunar\Models\TaxZoneCountry::class, ['tax_zone_id' => $zone->id]);
assertDatabaseHas(\Lunar\Models\TaxZoneCustomerGroup::class, ['tax_zone_id' => $zone->id]);
assertDatabaseHas(\Lunar\Models\TaxZoneState::class, ['tax_zone_id' => $zone->id]);
assertDatabaseHas(\Lunar\Models\TaxZonePostcode::class, ['tax_zone_id' => $zone->id]);
assertDatabaseHas(\Lunar\Models\TaxRate::class, ['tax_zone_id' => $zone->id]);

$zone->delete();

assertDatabaseMissing(\Lunar\Models\TaxZoneCountry::class, ['tax_zone_id' => $zone->id]);
assertDatabaseMissing(\Lunar\Models\TaxZoneCustomerGroup::class, ['tax_zone_id' => $zone->id]);
assertDatabaseMissing(\Lunar\Models\TaxZoneState::class, ['tax_zone_id' => $zone->id]);
assertDatabaseMissing(\Lunar\Models\TaxZonePostcode::class, ['tax_zone_id' => $zone->id]);
assertDatabaseMissing(\Lunar\Models\TaxRate::class, ['tax_zone_id' => $zone->id]);
})->group('foo');

0 comments on commit 806009b

Please sign in to comment.