Skip to content

Commit 643862a

Browse files
authored
Merge pull request #32 from hoyvoy/master
Added support to Polymorphic relations
2 parents 131a353 + 91ec5b9 commit 643862a

File tree

9 files changed

+268
-4
lines changed

9 files changed

+268
-4
lines changed

src/SoftCascade.php

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,15 @@ protected function relations($model, $foreignKeyIds)
9090
$foreignKeyIdsUse = $foreignKeyIds;
9191

9292
//Many to many relations need to get related ids and related local key
93-
if (get_class($modelRelation) == 'Illuminate\Database\Eloquent\Relations\BelongsToMany') {
94-
extract($this->gettBelongsToManyData($modelRelation, $foreignKeyIds));
93+
$classModelRelation = get_class($modelRelation);
94+
if ($classModelRelation == 'Illuminate\Database\Eloquent\Relations\BelongsToMany') {
95+
extract($this->getBelongsToManyData($modelRelation, $foreignKeyIds));
96+
} else if ($classModelRelation == 'Illuminate\Database\Eloquent\Relations\MorphMany') {
97+
extract($this->getMorphManyData($modelRelation, $foreignKeyIds));
9598
}
9699

97100
$affectedRowsOnExecute = $this->affectedRowsOnExecute($modelRelation, $foreignKeyUse, $foreignKeyIdsUse);
98-
101+
99102
if ($action === 'restrict' && $affectedRowsOnExecute > 0) {
100103
DB::rollBack(); //Rollback the transaction before throw exception
101104
throw (new SoftCascadeRestrictedException)->setModel(get_class($modelRelation->getModel()), $foreignKeyUse, $foreignKeyIdsUse->toArray());
@@ -112,7 +115,7 @@ protected function relations($model, $foreignKeyIds)
112115
* @param array $foreignKeyIds
113116
* @return array
114117
*/
115-
protected function gettBelongsToManyData($relation, $foreignKeyIds)
118+
protected function getBelongsToManyData($relation, $foreignKeyIds)
116119
{
117120
$relationConnectionName = $relation->getConnection()->getName();
118121
$relationTable = $relation->getTable();
@@ -133,6 +136,30 @@ protected function gettBelongsToManyData($relation, $foreignKeyIds)
133136
];
134137
}
135138

139+
/**
140+
* Get morph many related key ids and key use
141+
*
142+
* @param Illuminate\Database\Eloquent\Relations\Relation $relation
143+
* @param array $foreignKeyIds
144+
* @return array
145+
*/
146+
protected function getMorphManyData($relation, $foreignKeyIds)
147+
{
148+
$relationConnectionName = $relation->getConnection()->getName();
149+
$relatedClass = $relation->getRelated();
150+
$foreignKeyUse = $relatedClass->getKeyName();
151+
$foreignKeyIdsUse = $relatedClass::where($relation->getMorphType(), $relation->getMorphClass())
152+
->whereIn($relation->getQualifiedForeignKeyName(), $foreignKeyIds)
153+
->select($foreignKeyUse)
154+
->get()->toArray();
155+
$foreignKeyIdsUse = array_column($foreignKeyIdsUse, $foreignKeyUse);
156+
157+
return [
158+
'foreignKeyIdsUse' => collect($foreignKeyIdsUse),
159+
'foreignKeyUse' => $relation->getRelated()->getKeyName()
160+
];
161+
}
162+
136163
/**
137164
* Execute delete, or restore.
138165
*

tests/App/Comment.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Askedio\Tests\App;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class Comment extends Model
8+
{
9+
use \Illuminate\Database\Eloquent\SoftDeletes;
10+
11+
protected $table = 'comments';
12+
13+
protected $fillable = ['body'];
14+
15+
/**
16+
* Get all of the owning commentable models.
17+
*/
18+
public function commentable()
19+
{
20+
return $this->morphTo();
21+
}
22+
}

tests/App/Post.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Askedio\Tests\App;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class Post extends Model
8+
{
9+
use \Illuminate\Database\Eloquent\SoftDeletes;
10+
use \Askedio\SoftCascade\Traits\SoftCascadeTrait;
11+
use \Illuminate\Database\Eloquent\SoftDeletes;
12+
13+
protected $table = 'posts';
14+
15+
protected $fillable = ['title', 'body'];
16+
17+
protected $softCascade = ['comments'];
18+
19+
/**
20+
* Get all of the post's comments.
21+
*/
22+
public function comments()
23+
{
24+
return $this->morphMany('Askedio\Tests\App\Comment', 'commentable');
25+
}
26+
}

tests/App/Video.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Askedio\Tests\App;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class Video extends Model
8+
{
9+
use \Illuminate\Database\Eloquent\SoftDeletes;
10+
use \Askedio\SoftCascade\Traits\SoftCascadeTrait;
11+
use \Illuminate\Database\Eloquent\SoftDeletes;
12+
13+
protected $table = 'videos';
14+
15+
protected $fillable = ['title', 'url'];
16+
17+
protected $softCascade = ['comments'];
18+
19+
/**
20+
* Get all of the video's comments.
21+
*/
22+
public function comments()
23+
{
24+
return $this->morphMany('Askedio\Tests\App\Comment', 'commentable');
25+
}
26+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
6+
class CreatePostsTable extends Migration
7+
{
8+
/**
9+
* Run the migrations.
10+
*
11+
* @return void
12+
*/
13+
public function up()
14+
{
15+
DB::connection()->getSchemaBuilder()->create('posts', function (Blueprint $table) {
16+
$table->increments('id');
17+
$table->string('title', 100);
18+
$table->text('body');
19+
$table->timestamps();
20+
$table->softDeletes();
21+
});
22+
}
23+
24+
/**
25+
* Reverse the migrations.
26+
*
27+
* @return void
28+
*/
29+
public function down()
30+
{
31+
DB::connection()->getSchemaBuilder()->dropIfExists('posts');
32+
}
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
6+
class CreateVideosTable extends Migration
7+
{
8+
/**
9+
* Run the migrations.
10+
*
11+
* @return void
12+
*/
13+
public function up()
14+
{
15+
DB::connection()->getSchemaBuilder()->create('videos', function (Blueprint $table) {
16+
$table->increments('id');
17+
$table->string('title', 100);
18+
$table->string('url', 255);
19+
$table->timestamps();
20+
$table->softDeletes();
21+
});
22+
}
23+
24+
/**
25+
* Reverse the migrations.
26+
*
27+
* @return void
28+
*/
29+
public function down()
30+
{
31+
DB::connection()->getSchemaBuilder()->dropIfExists('videos');
32+
}
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
6+
class CreateCommentsTable extends Migration
7+
{
8+
/**
9+
* Run the migrations.
10+
*
11+
* @return void
12+
*/
13+
public function up()
14+
{
15+
DB::connection()->getSchemaBuilder()->create('comments', function (Blueprint $table) {
16+
$table->increments('id');
17+
$table->string('body', 255);
18+
$table->morphs('commentable');
19+
$table->timestamps();
20+
$table->softDeletes();
21+
});
22+
}
23+
24+
/**
25+
* Reverse the migrations.
26+
*
27+
* @return void
28+
*/
29+
public function down()
30+
{
31+
DB::connection()->getSchemaBuilder()->dropIfExists('comments');
32+
}
33+
}

tests/IntegrationTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
use Askedio\Tests\App\BadRelation;
77
use Askedio\Tests\App\BadRelationAction;
88
use Askedio\Tests\App\BadRelationB;
9+
use Askedio\Tests\App\Comment;
910
use Askedio\Tests\App\Languages;
11+
use Askedio\Tests\App\Post;
1012
use Askedio\Tests\App\Profiles;
1113
use Askedio\Tests\App\User;
14+
use Askedio\Tests\App\Video;
1215

1316
/**
1417
* TO-DO: Need better testing.
@@ -42,6 +45,35 @@ private function createUserRaw()
4245
return $user;
4346
}
4447

48+
private function createCommentRaw()
49+
{
50+
$post = Post::create([
51+
'title' => 'Post',
52+
'body' => 'Post chulo'
53+
])->comments()->saveMany([
54+
new Comment(['body' => 'comentario post']),
55+
]);
56+
57+
$video = Video::create([
58+
'title' => 'Video',
59+
'url' => 'Video chulo'
60+
])->comments()->saveMany([
61+
new Comment(['body' => 'comentario video']),
62+
]);
63+
64+
return $this;
65+
}
66+
67+
public function testPolymorphicRelation()
68+
{
69+
$this->createCommentRaw();
70+
71+
Post::first()->delete();
72+
73+
$this->assertDatabaseHas('videos', ['deleted_at' => null]);
74+
$this->assertDatabaseMissing('posts', ['deleted_at' => null]);
75+
}
76+
4577
public function testBadRelation()
4678
{
4779
$this->createUserRaw();

tests/LumenIntegrationTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
use Askedio\Tests\App\BadRelation;
77
use Askedio\Tests\App\BadRelationAction;
88
use Askedio\Tests\App\BadRelationB;
9+
use Askedio\Tests\App\Comment;
910
use Askedio\Tests\App\Languages;
11+
use Askedio\Tests\App\Post;
1012
use Askedio\Tests\App\Profiles;
1113
use Askedio\Tests\App\User;
14+
use Askedio\Tests\App\Video;
1215

1316
/**
1417
* TO-DO: Need better testing.
@@ -46,6 +49,35 @@ private function createUserRaw()
4649
return $user;
4750
}
4851

52+
private function createCommentRaw()
53+
{
54+
$post = Post::create([
55+
'title' => 'Post',
56+
'body' => 'Post chulo'
57+
])->comments()->saveMany([
58+
new Comment(['body' => 'comentario post']),
59+
]);
60+
61+
$video = Video::create([
62+
'title' => 'Video',
63+
'url' => 'Video chulo'
64+
])->comments()->saveMany([
65+
new Comment(['body' => 'comentario video']),
66+
]);
67+
68+
return $this;
69+
}
70+
71+
public function testPolymorphicRelation()
72+
{
73+
$this->createCommentRaw();
74+
75+
Post::first()->delete();
76+
77+
$this->assertDatabaseHas('videos', ['deleted_at' => null]);
78+
$this->assertDatabaseMissing('posts', ['deleted_at' => null]);
79+
}
80+
4981
public function testBadRelation()
5082
{
5183
$this->createUserRaw();

0 commit comments

Comments
 (0)