Support saving deferred bindings with pivot data. (#5466)
* Support saving deferred bindings with pivot data.
This commit is contained in:
parent
12520828ba
commit
d865186ac1
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
use October\Rain\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class DbAddPivotDataToDeferredBindings extends Migration
|
||||
{
|
||||
|
||||
public function up()
|
||||
{
|
||||
Schema::table('deferred_bindings', function (Blueprint $table) {
|
||||
$table->mediumText('pivot_data')->nullable()->after('slave_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::table('deferred_bindings', function (Blueprint $table) {
|
||||
$table->dropColumn('pivot_data');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -51,6 +51,15 @@ class Author extends Model
|
|||
public $morphOne = [
|
||||
'meta' => ['Database\Tester\Models\Meta', 'name' => 'taggable'],
|
||||
];
|
||||
|
||||
public $morphToMany = [
|
||||
'tags' => [
|
||||
'Database\Tester\Models\Tag',
|
||||
'name' => 'taggable',
|
||||
'table' => 'database_tester_taggables',
|
||||
'pivot' => ['added_by']
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
class SoftDeleteAuthor extends Author
|
||||
|
|
|
|||
|
|
@ -9,6 +9,14 @@ class Category extends Model
|
|||
*/
|
||||
public $table = 'database_tester_categories';
|
||||
|
||||
public $belongsToMany = [
|
||||
'posts' => [
|
||||
'Database\Tester\Models\Post',
|
||||
'table' => 'database_tester_categories_posts',
|
||||
'pivot' => ['category_name', 'post_name']
|
||||
]
|
||||
];
|
||||
|
||||
public function getCustomNameAttribute()
|
||||
{
|
||||
return $this->name.' (#'.$this->id.')';
|
||||
|
|
|
|||
|
|
@ -26,6 +26,14 @@ class Post extends Model
|
|||
'author' => 'Database\Tester\Models\Author',
|
||||
];
|
||||
|
||||
public $belongsToMany = [
|
||||
'categories' => [
|
||||
'Database\Tester\Models\Category',
|
||||
'table' => 'database_tester_categories_posts',
|
||||
'pivot' => ['category_name', 'post_name']
|
||||
]
|
||||
];
|
||||
|
||||
public $morphMany = [
|
||||
'event_log' => ['Database\Tester\Models\EventLog', 'name' => 'related', 'delete' => true, 'softDelete' => true],
|
||||
];
|
||||
|
|
@ -33,6 +41,15 @@ class Post extends Model
|
|||
public $morphOne = [
|
||||
'meta' => ['Database\Tester\Models\Meta', 'name' => 'taggable'],
|
||||
];
|
||||
|
||||
public $morphToMany = [
|
||||
'tags' => [
|
||||
'Database\Tester\Models\Tag',
|
||||
'name' => 'taggable',
|
||||
'table' => 'database_tester_taggables',
|
||||
'pivot' => ['added_by']
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
class NullablePost extends Post
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
<?php namespace Database\Tester\Models;
|
||||
|
||||
use Model;
|
||||
|
||||
class Tag extends Model
|
||||
{
|
||||
/**
|
||||
* @var string The database table used by the model.
|
||||
*/
|
||||
public $table = 'database_tester_tags';
|
||||
|
||||
/**
|
||||
* @var array Guarded fields
|
||||
*/
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* @var array Fillable fields
|
||||
*/
|
||||
protected $fillable = [];
|
||||
|
||||
public $morphedByMany = [
|
||||
'authors' => [
|
||||
'Database\Tester\Models\Author',
|
||||
'name' => 'taggable',
|
||||
'table' => 'database_tester_taggables',
|
||||
'pivot' => ['added_by'],
|
||||
],
|
||||
'posts' => [
|
||||
'Database\Tester\Models\Post',
|
||||
'name' => 'taggable',
|
||||
'table' => 'database_tester_taggables',
|
||||
'pivot' => ['added_by'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
|
@ -22,10 +22,20 @@ class CreatePostsTable extends Migration
|
|||
$table->softDeletes();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('database_tester_categories_posts', function ($table) {
|
||||
$table->engine = 'InnoDB';
|
||||
$table->integer('category_id')->unsigned();
|
||||
$table->integer('post_id')->unsigned();
|
||||
$table->primary(['category_id', 'post_id']);
|
||||
$table->string('category_name')->nullable();
|
||||
$table->string('post_name')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('database_tester_categories_posts');
|
||||
Schema::dropIfExists('database_tester_posts');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
<?php namespace Database\Tester\Updates;
|
||||
|
||||
use Schema;
|
||||
use October\Rain\Database\Updates\Migration;
|
||||
|
||||
class CreateTagsTable extends Migration
|
||||
{
|
||||
|
||||
public function up()
|
||||
{
|
||||
Schema::create('database_tester_tags', function ($table) {
|
||||
$table->engine = 'InnoDB';
|
||||
$table->increments('id');
|
||||
$table->string('name');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('database_tester_taggables', function ($table) {
|
||||
$table->engine = 'InnoDB';
|
||||
$table->unsignedInteger('tag_id');
|
||||
$table->morphs('taggable', 'testings_taggable');
|
||||
$table->unsignedInteger('added_by')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('database_tester_taggables');
|
||||
Schema::dropIfExists('database_tester_tags');
|
||||
}
|
||||
}
|
||||
|
|
@ -10,3 +10,4 @@
|
|||
- create_event_log_table.php
|
||||
- create_meta_table.php
|
||||
- create_countries_table.php
|
||||
- create_tags_table.php
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
use Database\Tester\Models\Category;
|
||||
use Database\Tester\Models\Post as PostModel;
|
||||
use Database\Tester\Models\Role;
|
||||
use Database\Tester\Models\Author;
|
||||
|
||||
|
|
@ -11,6 +13,8 @@ class BelongsToManyModelTest extends PluginTestCase
|
|||
|
||||
include_once base_path().'/tests/fixtures/plugins/database/tester/models/Role.php';
|
||||
include_once base_path().'/tests/fixtures/plugins/database/tester/models/Author.php';
|
||||
include_once base_path().'/tests/fixtures/plugins/database/tester/models/Category.php';
|
||||
include_once base_path().'/tests/fixtures/plugins/database/tester/models/Post.php';
|
||||
|
||||
$this->runPluginRefreshCommand('Database.Tester');
|
||||
}
|
||||
|
|
@ -86,29 +90,57 @@ class BelongsToManyModelTest extends PluginTestCase
|
|||
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@email.tld']);
|
||||
$role1 = Role::create(['name' => "Designer", 'description' => "Quality"]);
|
||||
$role2 = Role::create(['name' => "Programmer", 'description' => "Speed"]);
|
||||
|
||||
$category = Category::create(['name' => 'News']);
|
||||
$post1 = PostModel::create(['title' => 'First post']);
|
||||
$post2 = PostModel::create(['title' => 'Second post']);
|
||||
Model::reguard();
|
||||
|
||||
// Deferred add
|
||||
$author->roles()->add($role1, $sessionKey);
|
||||
$author->roles()->add($role2, $sessionKey);
|
||||
$category->posts()->add($post1, $sessionKey, [
|
||||
'category_name' => $category->name . ' in pivot',
|
||||
'post_name' => $post1->title . ' in pivot',
|
||||
]);
|
||||
$category->posts()->add($post2, $sessionKey, [
|
||||
'category_name' => $category->name . ' in pivot',
|
||||
'post_name' => $post2->title . ' in pivot',
|
||||
]);
|
||||
$this->assertEmpty($author->roles);
|
||||
$this->assertEmpty($category->posts);
|
||||
|
||||
$this->assertEquals(0, $author->roles()->count());
|
||||
$this->assertEquals(2, $author->roles()->withDeferred($sessionKey)->count());
|
||||
$this->assertEquals(0, $category->posts()->count());
|
||||
$this->assertEquals(2, $category->posts()->withDeferred($sessionKey)->count());
|
||||
|
||||
// Get simple value (implicit)
|
||||
$author->reloadRelations();
|
||||
$author->sessionKey = $sessionKey;
|
||||
$this->assertEquals([$role1->id, $role2->id], $author->getRelationValue('roles'));
|
||||
$category->reloadRelations();
|
||||
$category->sessionKey = $sessionKey;
|
||||
$this->assertEquals([$post1->id, $post2->id], $category->getRelationValue('posts'));
|
||||
|
||||
// Get simple value (explicit)
|
||||
$relatedIds = $author->roles()->allRelatedIds($sessionKey)->all();
|
||||
$this->assertEquals([$role1->id, $role2->id], $relatedIds);
|
||||
$relatedIds = $category->posts()->allRelatedIds($sessionKey)->all();
|
||||
$this->assertEquals([$post1->id, $post2->id], $relatedIds);
|
||||
|
||||
// Commit deferred
|
||||
$author->save(null, $sessionKey);
|
||||
$category->save(null, $sessionKey);
|
||||
$this->assertEquals(2, $author->roles()->count());
|
||||
$this->assertEquals('Designer', $author->roles->first()->name);
|
||||
$this->assertEquals(2, $category->posts()->count());
|
||||
$this->assertEquals('First post', $category->posts->first()->title);
|
||||
$this->assertEquals('Second post', $category->posts->last()->title);
|
||||
$this->assertEquals('First post in pivot', $category->posts->first()->pivot->post_name);
|
||||
$this->assertEquals('Second post in pivot', $category->posts->last()->pivot->post_name);
|
||||
$this->assertEquals('News in pivot', $category->posts->first()->pivot->category_name);
|
||||
$this->assertEquals('News in pivot', $category->posts->last()->pivot->category_name);
|
||||
|
||||
// New session
|
||||
$sessionKey = uniqid('session_key', true);
|
||||
|
|
@ -116,14 +148,27 @@ class BelongsToManyModelTest extends PluginTestCase
|
|||
// Deferred remove
|
||||
$author->roles()->remove($role1, $sessionKey);
|
||||
$author->roles()->remove($role2, $sessionKey);
|
||||
$category->posts()->remove($post1, $sessionKey);
|
||||
$category->posts()->remove($post2, $sessionKey);
|
||||
$this->assertEquals(2, $author->roles()->count());
|
||||
$this->assertEquals(0, $author->roles()->withDeferred($sessionKey)->count());
|
||||
$this->assertEquals(2, $category->posts()->count());
|
||||
$this->assertEquals(0, $category->posts()->withDeferred($sessionKey)->count());
|
||||
$this->assertEquals('Designer', $author->roles->first()->name);
|
||||
$this->assertEquals('First post', $category->posts->first()->title);
|
||||
$this->assertEquals('Second post', $category->posts->last()->title);
|
||||
$this->assertEquals('First post in pivot', $category->posts->first()->pivot->post_name);
|
||||
$this->assertEquals('Second post in pivot', $category->posts->last()->pivot->post_name);
|
||||
$this->assertEquals('News in pivot', $category->posts->first()->pivot->category_name);
|
||||
$this->assertEquals('News in pivot', $category->posts->last()->pivot->category_name);
|
||||
|
||||
// Commit deferred
|
||||
$author->save(null, $sessionKey);
|
||||
$category->save(null, $sessionKey);
|
||||
$this->assertEquals(0, $author->roles()->count());
|
||||
$this->assertEquals(0, $author->roles->count());
|
||||
$this->assertEquals(0, $category->posts()->count());
|
||||
$this->assertEquals(0, $category->posts->count());
|
||||
}
|
||||
|
||||
public function testDetachAfterDelete()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
|
||||
use Database\Tester\Models\Author;
|
||||
use Database\Tester\Models\Tag;
|
||||
use Database\Tester\Models\Post;
|
||||
use Database\Tester\Models\EventLog;
|
||||
use October\Rain\Database\Collection;
|
||||
|
||||
|
|
@ -11,7 +13,9 @@ class MorphManyModelTest extends PluginTestCase
|
|||
parent::setUp();
|
||||
|
||||
include_once base_path().'/tests/fixtures/plugins/database/tester/models/Author.php';
|
||||
include_once base_path().'/tests/fixtures/plugins/database/tester/models/Post.php';
|
||||
include_once base_path().'/tests/fixtures/plugins/database/tester/models/EventLog.php';
|
||||
include_once base_path().'/tests/fixtures/plugins/database/tester/models/Tag.php';
|
||||
|
||||
$this->runPluginRefreshCommand('Database.Tester');
|
||||
}
|
||||
|
|
@ -84,6 +88,9 @@ class MorphManyModelTest extends PluginTestCase
|
|||
Model::unguard();
|
||||
$author = Author::create(['name' => 'Stevie']);
|
||||
$event = EventLog::create(['action' => "user-created"]);
|
||||
$post = Post::create(['title' => 'Hello world!']);
|
||||
$tagForAuthor = Tag::create(['name' => 'ForAuthor']);
|
||||
$tagForPost = Tag::create(['name' => 'ForPost']);
|
||||
Model::reguard();
|
||||
|
||||
$eventId = $event->id;
|
||||
|
|
@ -96,6 +103,18 @@ class MorphManyModelTest extends PluginTestCase
|
|||
$this->assertEquals(0, $author->event_log()->count());
|
||||
$this->assertEquals(1, $author->event_log()->withDeferred($sessionKey)->count());
|
||||
|
||||
$author->tags()->add($tagForAuthor, $sessionKey, ['added_by' => 99]);
|
||||
$this->assertEmpty($author->tags);
|
||||
|
||||
$this->assertEquals(0, $author->tags()->count());
|
||||
$this->assertEquals(1, $author->tags()->withDeferred($sessionKey)->count());
|
||||
|
||||
$tagForPost->posts()->add($post, $sessionKey, ['added_by' => 88]);
|
||||
$this->assertEmpty($tagForPost->posts);
|
||||
|
||||
$this->assertEquals(0, $tagForPost->posts()->count());
|
||||
$this->assertEquals(1, $tagForPost->posts()->withDeferred($sessionKey)->count());
|
||||
|
||||
// Commit deferred
|
||||
$author->save(null, $sessionKey);
|
||||
$event = EventLog::find($eventId);
|
||||
|
|
@ -105,6 +124,15 @@ class MorphManyModelTest extends PluginTestCase
|
|||
'user-created'
|
||||
], $author->event_log->lists('action'));
|
||||
|
||||
$this->assertEquals(1, $author->tags()->count());
|
||||
$this->assertEquals([$tagForAuthor->id], $author->tags->lists('id'));
|
||||
$this->assertEquals(99, $author->tags->first()->pivot->added_by);
|
||||
|
||||
$tagForPost->save(null, $sessionKey);
|
||||
$this->assertEquals(1, $tagForPost->posts()->count());
|
||||
$this->assertEquals([$post->id], $tagForPost->posts->lists('id'));
|
||||
$this->assertEquals(88, $tagForPost->posts->first()->pivot->added_by);
|
||||
|
||||
// New session
|
||||
$sessionKey = uniqid('session_key', true);
|
||||
|
||||
|
|
@ -117,11 +145,27 @@ class MorphManyModelTest extends PluginTestCase
|
|||
'user-created'
|
||||
], $author->event_log->lists('action'));
|
||||
|
||||
$author->tags()->remove($tagForAuthor, $sessionKey);
|
||||
$this->assertEquals(1, $author->tags()->count());
|
||||
$this->assertEquals(0, $author->tags()->withDeferred($sessionKey)->count());
|
||||
$this->assertEquals([$tagForAuthor->id], $author->tags->lists('id'));
|
||||
$this->assertEquals(99, $author->tags->first()->pivot->added_by);
|
||||
|
||||
$tagForPost->posts()->remove($post, $sessionKey);
|
||||
$this->assertEquals(1, $tagForPost->posts()->count());
|
||||
$this->assertEquals(0, $tagForPost->posts()->withDeferred($sessionKey)->count());
|
||||
$this->assertEquals([$post->id], $tagForPost->posts->lists('id'));
|
||||
$this->assertEquals(88, $tagForPost->posts->first()->pivot->added_by);
|
||||
|
||||
|
||||
// Commit deferred (model is deleted as per definition)
|
||||
$author->save(null, $sessionKey);
|
||||
$event = EventLog::find($eventId);
|
||||
$this->assertEquals(0, $author->event_log()->count());
|
||||
$this->assertNull($event);
|
||||
$this->assertEmpty($author->event_log);
|
||||
|
||||
$this->assertEmpty(0, $author->tags);
|
||||
$this->assertEmpty(0, $tagForPost->posts);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue