EloquentHasManyThroughTest.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. namespace Illuminate\Tests\Integration\Database\EloquentHasManyThroughTest;
  3. use Illuminate\Database\Eloquent\Model;
  4. use Illuminate\Database\Eloquent\SoftDeletes;
  5. use Illuminate\Database\Schema\Blueprint;
  6. use Illuminate\Support\Facades\Schema;
  7. use Illuminate\Support\Str;
  8. use Illuminate\Tests\Integration\Database\DatabaseTestCase;
  9. class EloquentHasManyThroughTest extends DatabaseTestCase
  10. {
  11. protected function defineDatabaseMigrationsAfterDatabaseRefreshed()
  12. {
  13. Schema::create('users', function (Blueprint $table) {
  14. $table->increments('id');
  15. $table->string('slug')->nullable();
  16. $table->integer('team_id')->nullable();
  17. $table->string('name');
  18. });
  19. Schema::create('teams', function (Blueprint $table) {
  20. $table->increments('id');
  21. $table->integer('owner_id')->nullable();
  22. $table->string('owner_slug')->nullable();
  23. });
  24. Schema::create('categories', function (Blueprint $table) {
  25. $table->increments('id');
  26. $table->integer('parent_id')->nullable();
  27. $table->softDeletes();
  28. });
  29. Schema::create('products', function (Blueprint $table) {
  30. $table->increments('id');
  31. $table->integer('category_id');
  32. });
  33. }
  34. public function testBasicCreateAndRetrieve()
  35. {
  36. $user = User::create(['name' => Str::random()]);
  37. $team1 = Team::create(['owner_id' => $user->id]);
  38. $team2 = Team::create(['owner_id' => $user->id]);
  39. $mate1 = User::create(['name' => 'John', 'team_id' => $team1->id]);
  40. $mate2 = User::create(['name' => 'Jack', 'team_id' => $team2->id, 'slug' => null]);
  41. User::create(['name' => Str::random()]);
  42. $this->assertEquals([$mate1->id, $mate2->id], $user->teamMates->pluck('id')->toArray());
  43. $this->assertEquals([$user->id], User::has('teamMates')->pluck('id')->toArray());
  44. $result = $user->teamMates()->first();
  45. $this->assertEquals(
  46. $mate1->refresh()->getAttributes() + ['laravel_through_key' => '1'],
  47. $result->getAttributes()
  48. );
  49. $result = $user->teamMates()->firstWhere('name', 'Jack');
  50. $this->assertEquals(
  51. $mate2->refresh()->getAttributes() + ['laravel_through_key' => '1'],
  52. $result->getAttributes()
  53. );
  54. }
  55. public function testGlobalScopeColumns()
  56. {
  57. $user = User::create(['name' => Str::random()]);
  58. $team1 = Team::create(['owner_id' => $user->id]);
  59. User::create(['name' => Str::random(), 'team_id' => $team1->id]);
  60. $teamMates = $user->teamMatesWithGlobalScope;
  61. $this->assertEquals(['id' => 2, 'laravel_through_key' => 1], $teamMates[0]->getAttributes());
  62. }
  63. public function testHasSelf()
  64. {
  65. $user = User::create(['name' => Str::random()]);
  66. $team = Team::create(['owner_id' => $user->id]);
  67. User::create(['name' => Str::random(), 'team_id' => $team->id]);
  68. $users = User::has('teamMates')->get();
  69. $this->assertCount(1, $users);
  70. }
  71. public function testHasSelfCustomOwnerKey()
  72. {
  73. $user = User::create(['slug' => Str::random(), 'name' => Str::random()]);
  74. $team = Team::create(['owner_slug' => $user->slug]);
  75. User::create(['name' => Str::random(), 'team_id' => $team->id]);
  76. $users = User::has('teamMatesBySlug')->get();
  77. $this->assertCount(1, $users);
  78. }
  79. public function testHasSameParentAndThroughParentTable()
  80. {
  81. Category::create();
  82. Category::create();
  83. Category::create(['parent_id' => 1]);
  84. Category::create(['parent_id' => 2])->delete();
  85. Product::create(['category_id' => 3]);
  86. Product::create(['category_id' => 4]);
  87. $categories = Category::has('subProducts')->get();
  88. $this->assertEquals([1], $categories->pluck('id')->all());
  89. }
  90. }
  91. class User extends Model
  92. {
  93. public $table = 'users';
  94. public $timestamps = false;
  95. protected $guarded = [];
  96. public function teamMates()
  97. {
  98. return $this->hasManyThrough(self::class, Team::class, 'owner_id', 'team_id');
  99. }
  100. public function teamMatesBySlug()
  101. {
  102. return $this->hasManyThrough(self::class, Team::class, 'owner_slug', 'team_id', 'slug');
  103. }
  104. public function teamMatesWithGlobalScope()
  105. {
  106. return $this->hasManyThrough(UserWithGlobalScope::class, Team::class, 'owner_id', 'team_id');
  107. }
  108. }
  109. class UserWithGlobalScope extends Model
  110. {
  111. public $table = 'users';
  112. public $timestamps = false;
  113. protected $guarded = [];
  114. public static function boot()
  115. {
  116. parent::boot();
  117. static::addGlobalScope(function ($query) {
  118. $query->select('users.id');
  119. });
  120. }
  121. }
  122. class Team extends Model
  123. {
  124. public $table = 'teams';
  125. public $timestamps = false;
  126. protected $guarded = [];
  127. }
  128. class Category extends Model
  129. {
  130. use SoftDeletes;
  131. public $timestamps = false;
  132. protected $guarded = [];
  133. public function subProducts()
  134. {
  135. return $this->hasManyThrough(Product::class, self::class, 'parent_id');
  136. }
  137. }
  138. class Product extends Model
  139. {
  140. public $timestamps = false;
  141. protected $guarded = [];
  142. }