Skip to content

Commit

Permalink
Merge pull request #152 from ysfks/latest
Browse files Browse the repository at this point in the history
Add condition to skip retrieving models that are not cascadable
  • Loading branch information
gcphost authored Oct 23, 2024
2 parents 0ea4b91 + feadc15 commit c23a93e
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 15 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ tests/logs
build/

# PhpStorm
.idea
.idea

.phpunit.cache
11 changes: 10 additions & 1 deletion src/Listeners/CascadeQueryListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Askedio\SoftCascade\Listeners;

use Askedio\SoftCascade\QueryBuilderSoftCascade;
use Askedio\SoftCascade\Traits\ChecksCascading;
use BadMethodCallException;
use Illuminate\Database\Connection;
use Illuminate\Database\Eloquent\SoftDeletingScope;
Expand All @@ -11,6 +12,7 @@

class CascadeQueryListener
{
use ChecksCascading;
const EVENT = QueryExecuted::class;

/**
Expand Down Expand Up @@ -82,7 +84,14 @@ public function handle(): void
// otherwise, we can just skip it
}

$model = $builder->get([$builder->getModel()->getKeyName()]);
$keyName = $builder->getModel()->getKeyName();

if (!$this->hasCascadingRelations($builder->getModel()) or $keyName === null) {
// If model doesn't have any primary key, there will be no relations
return;
}

$model = $builder->get([$keyName]);
(new QueryBuilderSoftCascade())->cascade($model, $event['direction'], $event['directionData']);
}
}
Expand Down
17 changes: 4 additions & 13 deletions src/SoftCascade.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Askedio\SoftCascade\Exceptions\SoftCascadeLogicException;
use Askedio\SoftCascade\Exceptions\SoftCascadeNonExistentRelationActionException;
use Askedio\SoftCascade\Exceptions\SoftCascadeRestrictedException;
use Askedio\SoftCascade\Traits\ChecksCascading;
use BadMethodCallException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
Expand All @@ -14,6 +15,8 @@

class SoftCascade implements SoftCascadeable
{
use ChecksCascading;

protected $direction;
protected $directionData;
protected $availableActions = ['update', 'restrict'];
Expand Down Expand Up @@ -66,7 +69,7 @@ protected function run($models)
return;
}

if (!$this->isCascadable($model)) {
if (!$this->hasCascadingRelations($model)) {
return;
}

Expand Down Expand Up @@ -237,18 +240,6 @@ protected function validateRelation($model, $relation)
}
}

/**
* Check if the model is enabled to cascade.
*
* @param Illuminate\Database\Eloquent\Model $model
*
* @return bool
*/
protected function isCascadable($model)
{
return method_exists($model, 'getSoftCascade');
}

/**
* Affected rows if we do execute.
*
Expand Down
18 changes: 18 additions & 0 deletions src/Traits/ChecksCascading.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Askedio\SoftCascade\Traits;

trait ChecksCascading
{
/**
* Check if the model is enabled to cascade.
*
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return bool
*/
protected function hasCascadingRelations($model): bool
{
return method_exists($model, 'getSoftCascade');
}
}
18 changes: 18 additions & 0 deletions tests/App/Record.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Askedio\Tests\App;

use Illuminate\Database\Eloquent\Model;

class Record extends Model
{
public $primaryKey = null;

public $timestamps = false;

public $incrementing = false;

protected $table = 'records';

protected $fillable = ['record_id', 'time', 'value'];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateRecordsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
DB::connection()->getSchemaBuilder()->create('records', function (Blueprint $table) {
$table->string('record_id');
$table->float('value');
$table->timestamp('time');
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
DB::connection()->getSchemaBuilder()->dropIfExists('records');
}
}
29 changes: 29 additions & 0 deletions tests/IntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@
use Askedio\Tests\App\Languages;
use Askedio\Tests\App\Post;
use Askedio\Tests\App\Profiles;
use Askedio\Tests\App\Record;
use Askedio\Tests\App\RoleReader;
use Askedio\Tests\App\RoleWriter;
use Askedio\Tests\App\User;
use Askedio\Tests\App\Video;
use Illuminate\Database\Events\QueryExecuted;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Str;

/**
* TO-DO: Need better testing.
Expand Down Expand Up @@ -312,6 +316,31 @@ public function testInexistentRestrictedAction()
BadRelationAction::first()->delete();
}

public function testSkipCascadingModelsWithoutPrimaryKeys()
{
$testSelect = false;

Event::listen(QueryExecuted::class, function (QueryExecuted $event) use (&$testSelect) {
if ($testSelect && !Str::of($event->sql)->contains('delete', true)) {
$this->fail('Model shouldn\'t have been retrieved when it is not cascadable or its primary key is null');
}
});

$record = Record::create([
'record_id' => 'b61bc6dd-4cee-4fe2-8aed-d8eac5920532',
'time' => now()->subMonth(),
'value' => 134.12,
]);

$testSelect = true;

Record::query()->where('time', '<', now())->delete();

$testSelect = false;

$this->assertDatabaseMissing('records', ['record_id' => $record->record_id]);
}

// public function testNotCascadable()
// {
/*
Expand Down

0 comments on commit c23a93e

Please # to comment.