Skip to content

Commit

Permalink
Merge pull request #14 from korridor/master
Browse files Browse the repository at this point in the history
Added the ability to copy a many-to-many relationship with pivot attributes
  • Loading branch information
weotch authored Oct 22, 2018
2 parents 01be2b5 + 00553fc commit cc19dee
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 12 deletions.
10 changes: 8 additions & 2 deletions src/Cloner.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,14 @@ protected function duplicatePivotedRelation($relation, $relation_name, $clone) {
if ($this->write_connection) return;

// Loop trough current relations and attach to clone
$relation->get()->each(function($foreign) use ($clone, $relation_name) {
$clone->$relation_name()->attach($foreign);
$relation->get()->each(function ($foreign) use ($clone, $relation_name) {
$pivot_attributes = array_except($foreign->pivot->getAttributes(), [
$foreign->pivot->getRelatedKey(),
$foreign->pivot->getForeignKey(),
$foreign->pivot->getCreatedAtColumn(),
$foreign->pivot->getUpdatedAtColumn()
]);
$clone->$relation_name()->attach($foreign, $pivot_attributes);
});
}

Expand Down
6 changes: 5 additions & 1 deletion stubs/Article.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
class Article extends Eloquent {
use Cloneable;

public $cloneable_relations = ['photos', 'authors'];
public $cloneable_relations = ['photos', 'authors', 'ratings'];

public function photos() {
return $this->hasMany('Bkwld\Cloner\Stubs\Photo');
Expand All @@ -15,4 +15,8 @@ public function photos() {
public function authors() {
return $this->belongsToMany('Bkwld\Cloner\Stubs\Author');
}

public function ratings() {
return $this->belongsToMany(User::class)->withPivot('rating')->withTimestamps();
}
}
13 changes: 13 additions & 0 deletions stubs/User.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Bkwld\Cloner\Stubs;

use Illuminate\Database\Eloquent\Model as Eloquent;

class User extends Eloquent {

public function rated_articles() {
return $this->belongsToMany(Article::class)->withPivot('rating')->withTimestamps();
}

}
4 changes: 2 additions & 2 deletions tests/CloneableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function testDuplicateWithDifferentDB() {

public function testGetRelations() {
$article = new Article;
$this->assertEquals(['photos', 'authors'], $article->getCloneableRelations());
$this->assertEquals(['photos', 'authors', 'ratings'], $article->getCloneableRelations());
}

public function testAddRelation() {
Expand All @@ -50,7 +50,7 @@ public function testAddDuplicateRelation() {
$article = new Article;
$article->addCloneableRelation('test');
$article->addCloneableRelation('test');
$this->assertEquals(['photos', 'authors', 'test'], $article->getCloneableRelations());
$this->assertEquals(['photos', 'authors', 'ratings', 'test'], $article->getCloneableRelations());
}

}
59 changes: 52 additions & 7 deletions tests/FunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
use Bkwld\Cloner\Stubs\Article;
use Bkwld\Cloner\Stubs\Author;
use Bkwld\Cloner\Stubs\Photo;
use Bkwld\Cloner\Stubs\User;
use Bkwld\Upchuck\Helpers;
use Bkwld\Upchuck\Storage;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\Schema\Blueprint;
use League\Flysystem\Filesystem;
use League\Flysystem\Vfs\VfsAdapter as Adapter;
use League\Flysystem\MountManager;
Expand All @@ -17,7 +19,9 @@

class FunctionalTest extends PHPUnit_Framework_TestCase {

protected function initUpchuck() {
private $article;

protected function initUpchuck() {

// Setup filesystem
$fs = new Vfs;
Expand Down Expand Up @@ -68,32 +72,45 @@ protected function setUpDatabase() {

// https://github.com/laracasts/TestDummy/blob/master/tests/FactoryTest.php#L31
protected function migrateTables($connection = 'default') {
DB::connection($connection)->getSchemaBuilder()->create('articles', function ($table) {
DB::connection($connection)->getSchemaBuilder()->create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->timestamps();
});

DB::connection($connection)->getSchemaBuilder()->create('authors', function ($table) {
DB::connection($connection)->getSchemaBuilder()->create('authors', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});

DB::connection($connection)->getSchemaBuilder()->create('article_author', function ($table) {
DB::connection($connection)->getSchemaBuilder()->create('article_author', function (Blueprint $table) {
$table->increments('id');
$table->integer('article_id')->unsigned();
$table->integer('author_id')->unsigned();
});

DB::connection($connection)->getSchemaBuilder()->create('photos', function ($table) {
DB::connection($connection)->getSchemaBuilder()->create('photos', function (Blueprint $table) {
$table->increments('id');
$table->integer('article_id')->unsigned();
$table->string('uid');
$table->string('image');
$table->boolean('source')->nullable();
$table->timestamps();
});

DB::connection($connection)->getSchemaBuilder()->create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});

DB::connection($connection)->getSchemaBuilder()->create('article_user', function (Blueprint $table) {
$table->integer('rating')->unsigned();
$table->integer('user_id')->unsigned();
$table->integer('article_id')->unsigned();
$table->timestamps();
});
}

protected function seed() {
Expand All @@ -107,6 +124,12 @@ protected function seed() {
'name' => 'Steve',
]));

$this->article->ratings()->attach(User::create([
'name' => 'Peter'
]), [
'rating' => 4
]);

$this->disk->write('test.jpg', 'contents');

Photo::unguard();
Expand All @@ -124,6 +147,9 @@ function testExists() {
$this->migrateTables();
$this->seed();

// Wait 1.5 seconds to be able to detect a difference in the timestamps
usleep(1500000);

$cloner = new Cloner($this->upchuck_adapter, $this->mockEvents());
$clone = $cloner->duplicate($this->article);

Expand All @@ -132,11 +158,30 @@ function testExists() {
$this->assertEquals(2, $clone->id);
$this->assertEquals('Test', $clone->title);

// Test mamny to many
// Test if the timestamps have been reset
$this->assertNotNull($clone->created_at);
$this->assertTrue($this->article->created_at->lt($clone->created_at));
$this->assertNotNull($clone->updated_at);
$this->assertTrue($this->article->created_at->lt($clone->updated_at));

// Test many to many
$this->assertEquals(1, $clone->authors()->count());
$this->assertEquals('Steve', $clone->authors()->first()->name);
$this->assertEquals(2, DB::table('article_author')->count());

// Test many to many with pivot
$this->assertEquals(1, $clone->ratings()->count());
$this->assertEquals('Peter', $clone->ratings()->first()->name);
$this->assertEquals(2, DB::table('article_user')->count());

// Test if the timestamps in the pivot table have been reset
$this->assertNotNull($this->article->ratings()->first()->pivot->created_at);
$this->assertNotNull($clone->ratings()->first()->pivot->created_at);
$this->assertTrue($this->article->ratings()->first()->pivot->created_at->lt($clone->ratings()->first()->pivot->created_at));
$this->assertNotNull($this->article->ratings()->first()->pivot->updated_at);
$this->assertNotNull($clone->ratings()->first()->pivot->updated_at);
$this->assertTrue($this->article->ratings()->first()->pivot->updated_at->lt($clone->ratings()->first()->pivot->updated_at));

// Test one to many
$this->assertEquals(1, $clone->photos()->count());
$photo = $clone->photos()->first();
Expand Down Expand Up @@ -185,7 +230,7 @@ function testExistsInAltDatabaseAndFilesystem() {
$this->assertEquals(1 , $clone->id);
$this->assertEquals('Test', $clone->title);

// Test that mamny to many failed
// Test that many to many failed
$this->assertEquals(0, DB::connection('alt')->table('authors')
->where('article_id', $clone->id)->count());

Expand Down

0 comments on commit cc19dee

Please sign in to comment.