Skip to content

Commit 5511ee8

Browse files
authored
Merge pull request #105 from tsterker/fix-has-many-through
fix: HasManyThrough and HasOneThrough not working
2 parents c4f458f + f304838 commit 5511ee8

File tree

7 files changed

+144
-1
lines changed

7 files changed

+144
-1
lines changed

src/HasParent.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public static function bootHasParent(): void
3838
$instance = new static;
3939

4040
if ($instance->parentHasHasChildrenTrait()) {
41-
$query->where($instance->getTable().'.'.$instance->getInheritanceColumn(), $instance->classToAlias(get_class($instance)));
41+
$query->where($query->getModel()->getTable().'.'.$instance->getInheritanceColumn(), $instance->classToAlias(get_class($instance)));
4242
}
4343
});
4444
}

tests/Features/ChildModelsAreAutomaticallyScopedTest.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
use Parental\Tests\Models\Admin;
66
use Parental\Tests\Models\Car;
7+
use Parental\Tests\Models\ChildNode;
78
use Parental\Tests\Models\Driver;
9+
use Parental\Tests\Models\NodeEdge;
10+
use Parental\Tests\Models\ParentNode;
811
use Parental\Tests\Models\Passenger;
912
use Parental\Tests\Models\Trip;
1013
use Parental\Tests\Models\User;
@@ -71,4 +74,57 @@ function child_is_scoped_when_accessed_from_belongs_to_many()
7174
$this->assertCount(1, $trip->cars);
7275
$this->assertCount(2, $trip->vehicles);
7376
}
77+
78+
/** @test */
79+
function child_is_scoped_when_accessed_from_has_one_through()
80+
{
81+
// Create root with children
82+
$rootA = ParentNode::create(['name' => 'Root A']);
83+
$childA = ChildNode::create(['name' => 'Child 1']);
84+
$childB = ChildNode::create(['name' => 'Child 2']);
85+
$childC = ChildNode::create(['name' => 'Child 3']);
86+
NodeEdge::create(['parent_node_id' => $rootA->id, 'child_node_id' => $childA->id]);
87+
NodeEdge::create(['parent_node_id' => $rootA->id, 'child_node_id' => $childB->id]);
88+
89+
$this->assertInstanceOf(ParentNode::class, $childA->parent);
90+
$this->assertInstanceOf(ParentNode::class, $childB->parent);
91+
$this->assertNull($childC->parent);
92+
93+
$this->assertCount(2, ChildNode::whereHas('parent')->get());
94+
$this->assertTrue(ChildNode::whereId($childA->id)->whereHas('parent')->exists());
95+
$this->assertTrue(ChildNode::whereId($childB->id)->whereHas('parent')->exists());
96+
$this->assertFalse(ChildNode::whereId($childC->id)->whereHas('parent')->exists());
97+
}
98+
99+
/** @test */
100+
function child_is_scoped_when_accessed_from_has_many_through()
101+
{
102+
// Create root with children
103+
$rootA = ParentNode::create(['name' => 'Root A']);
104+
$childA = ChildNode::create(['name' => 'Child 1']);
105+
$childB = ChildNode::create(['name' => 'Child 2']);
106+
$childC = ChildNode::create(['name' => 'Child 3']);
107+
NodeEdge::create(['parent_node_id' => $rootA->id, 'child_node_id' => $childA->id]);
108+
NodeEdge::create(['parent_node_id' => $rootA->id, 'child_node_id' => $childB->id]);
109+
NodeEdge::create(['parent_node_id' => $rootA->id, 'child_node_id' => $childC->id]);
110+
111+
// Create different root with different children
112+
$rootB = ParentNode::create(['name' => 'Root B']);
113+
$childX = ChildNode::create(['name' => 'Child X']);
114+
NodeEdge::create(['parent_node_id' => $rootB->id, 'child_node_id' => $childX->id]);
115+
116+
// Create different root children any children
117+
$rootC = ParentNode::create(['name' => 'Root C']);
118+
119+
$this->assertCount(3, $rootA->children);
120+
$this->assertContainsOnlyInstancesOf(ChildNode::class, $rootA->children);
121+
122+
$this->assertCount(1, $rootB->children);
123+
$this->assertContainsOnlyInstancesOf(ChildNode::class, $rootB->children);
124+
125+
$this->assertCount(2, ParentNode::whereHas('children')->get());
126+
$this->assertTrue(ParentNode::whereId($rootA->id)->whereHas('children')->exists());
127+
$this->assertTrue(ParentNode::whereId($rootB->id)->whereHas('children')->exists());
128+
$this->assertFalse(ParentNode::whereId($rootC->id)->whereHas('children')->exists());
129+
}
74130
}

tests/Models/ChildNode.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Parental\Tests\Models;
4+
5+
use Parental\HasParent;
6+
7+
class ChildNode extends Node
8+
{
9+
use HasParent;
10+
11+
protected $guarded = [];
12+
13+
public function parent()
14+
{
15+
return $this->hasOneThrough(
16+
ParentNode::class,
17+
NodeEdge::class,
18+
'child_node_id',
19+
'id',
20+
'id',
21+
'parent_node_id',
22+
);
23+
}
24+
}

tests/Models/Node.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Parental\Tests\Models;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use Parental\HasChildren;
7+
8+
class Node extends Model
9+
{
10+
use HasChildren;
11+
12+
protected $guarded = [];
13+
}

tests/Models/NodeEdge.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Parental\Tests\Models;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class NodeEdge extends Model
8+
{
9+
protected $guarded = [];
10+
}

tests/Models/ParentNode.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Parental\Tests\Models;
4+
5+
use Parental\HasParent;
6+
7+
class ParentNode extends Node
8+
{
9+
use HasParent;
10+
11+
protected $guarded = [];
12+
13+
public function children()
14+
{
15+
return $this->hasManyThrough(
16+
ChildNode::class,
17+
NodeEdge::class,
18+
'parent_node_id',
19+
'id',
20+
'id',
21+
'child_node_id',
22+
);
23+
}
24+
}

tests/TestCase.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
use Illuminate\Database\Eloquent\Factories\Factory;
66
use Illuminate\Support\Facades\Schema;
77
use Orchestra\Testbench\TestCase as BaseTestCase;
8+
use Parental\Tests\Models\LeCredential;
9+
use Parental\Tests\Models\OorCredential;
810

911
class TestCase extends BaseTestCase
1012
{
@@ -82,5 +84,19 @@ public function runMigrations()
8284
$table->morphs('partable');
8385
$table->timestamps();
8486
});
87+
88+
Schema::create('nodes', function ($table) {
89+
$table->increments('id');
90+
$table->string('type');
91+
$table->string('name');
92+
$table->timestamps();
93+
});
94+
95+
Schema::create('node_edges', function ($table) {
96+
$table->increments('id');
97+
$table->string('parent_node_id');
98+
$table->string('child_node_id');
99+
$table->timestamps();
100+
});
85101
}
86102
}

0 commit comments

Comments
 (0)