EloquentCollectionLoadMissingTest.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. namespace Illuminate\Tests\Integration\Database\EloquentCollectionLoadMissingTest;
  3. use DB;
  4. use Illuminate\Database\Eloquent\Model;
  5. use Illuminate\Database\Schema\Blueprint;
  6. use Illuminate\Support\Facades\Schema;
  7. use Illuminate\Tests\Integration\Database\DatabaseTestCase;
  8. class EloquentCollectionLoadMissingTest extends DatabaseTestCase
  9. {
  10. protected function defineDatabaseMigrationsAfterDatabaseRefreshed()
  11. {
  12. Schema::create('users', function (Blueprint $table) {
  13. $table->increments('id');
  14. });
  15. Schema::create('posts', function (Blueprint $table) {
  16. $table->increments('id');
  17. $table->unsignedInteger('user_id');
  18. });
  19. Schema::create('comments', function (Blueprint $table) {
  20. $table->increments('id');
  21. $table->unsignedInteger('parent_id')->nullable();
  22. $table->unsignedInteger('post_id');
  23. });
  24. Schema::create('revisions', function (Blueprint $table) {
  25. $table->increments('id');
  26. $table->unsignedInteger('comment_id');
  27. });
  28. Schema::create('post_relations', function (Blueprint $table) {
  29. $table->increments('id');
  30. $table->unsignedInteger('post_id');
  31. });
  32. Schema::create('post_sub_relations', function (Blueprint $table) {
  33. $table->increments('id');
  34. $table->unsignedInteger('post_relation_id');
  35. });
  36. Schema::create('post_sub_sub_relations', function (Blueprint $table) {
  37. $table->increments('id');
  38. $table->unsignedInteger('post_sub_relation_id');
  39. });
  40. User::create();
  41. Post::create(['user_id' => 1]);
  42. Comment::create(['parent_id' => null, 'post_id' => 1]);
  43. Comment::create(['parent_id' => 1, 'post_id' => 1]);
  44. Comment::create(['parent_id' => 2, 'post_id' => 1]);
  45. Revision::create(['comment_id' => 1]);
  46. Post::create(['user_id' => 1]);
  47. PostRelation::create(['post_id' => 2]);
  48. PostSubRelation::create(['post_relation_id' => 1]);
  49. PostSubSubRelation::create(['post_sub_relation_id' => 1]);
  50. }
  51. public function testLoadMissing()
  52. {
  53. $posts = Post::with('comments', 'user')->get();
  54. DB::enableQueryLog();
  55. $posts->loadMissing('comments.parent.revisions:revisions.comment_id', 'user:id');
  56. $this->assertCount(2, DB::getQueryLog());
  57. $this->assertTrue($posts[0]->comments[0]->relationLoaded('parent'));
  58. $this->assertTrue($posts[0]->comments[1]->parent->relationLoaded('revisions'));
  59. $this->assertArrayNotHasKey('id', $posts[0]->comments[1]->parent->revisions[0]->getAttributes());
  60. }
  61. public function testLoadMissingWithClosure()
  62. {
  63. $posts = Post::with('comments')->get();
  64. DB::enableQueryLog();
  65. $posts->loadMissing(['comments.parent' => function ($query) {
  66. $query->select('id');
  67. }]);
  68. $this->assertCount(1, DB::getQueryLog());
  69. $this->assertTrue($posts[0]->comments[0]->relationLoaded('parent'));
  70. $this->assertArrayNotHasKey('post_id', $posts[0]->comments[1]->parent->getAttributes());
  71. }
  72. public function testLoadMissingWithDuplicateRelationName()
  73. {
  74. $posts = Post::with('comments')->get();
  75. DB::enableQueryLog();
  76. $posts->loadMissing('comments.parent.parent');
  77. $this->assertCount(2, DB::getQueryLog());
  78. $this->assertTrue($posts[0]->comments[0]->relationLoaded('parent'));
  79. $this->assertTrue($posts[0]->comments[1]->parent->relationLoaded('parent'));
  80. }
  81. public function testLoadMissingWithoutInitialLoad()
  82. {
  83. $user = User::first();
  84. $user->loadMissing('posts.postRelation.postSubRelations.postSubSubRelations');
  85. $this->assertEquals(2, $user->posts->count());
  86. $this->assertNull($user->posts[0]->postRelation);
  87. $this->assertInstanceOf(PostRelation::class, $user->posts[1]->postRelation);
  88. $this->assertEquals(1, $user->posts[1]->postRelation->postSubRelations->count());
  89. $this->assertInstanceOf(PostSubRelation::class, $user->posts[1]->postRelation->postSubRelations[0]);
  90. $this->assertEquals(1, $user->posts[1]->postRelation->postSubRelations[0]->postSubSubRelations->count());
  91. $this->assertInstanceOf(PostSubSubRelation::class, $user->posts[1]->postRelation->postSubRelations[0]->postSubSubRelations[0]);
  92. }
  93. }
  94. class Comment extends Model
  95. {
  96. public $timestamps = false;
  97. protected $guarded = [];
  98. public function parent()
  99. {
  100. return $this->belongsTo(self::class);
  101. }
  102. public function revisions()
  103. {
  104. return $this->hasMany(Revision::class);
  105. }
  106. }
  107. class Post extends Model
  108. {
  109. public $timestamps = false;
  110. protected $guarded = [];
  111. public function comments()
  112. {
  113. return $this->hasMany(Comment::class);
  114. }
  115. public function user()
  116. {
  117. return $this->belongsTo(User::class);
  118. }
  119. public function postRelation()
  120. {
  121. return $this->hasOne(PostRelation::class);
  122. }
  123. }
  124. class PostRelation extends Model
  125. {
  126. public $timestamps = false;
  127. protected $guarded = [];
  128. public function postSubRelations()
  129. {
  130. return $this->hasMany(PostSubRelation::class);
  131. }
  132. }
  133. class PostSubRelation extends Model
  134. {
  135. public $timestamps = false;
  136. protected $guarded = [];
  137. public function postSubSubRelations()
  138. {
  139. return $this->hasMany(PostSubSubRelation::class);
  140. }
  141. }
  142. class PostSubSubRelation extends Model
  143. {
  144. public $timestamps = false;
  145. protected $guarded = [];
  146. }
  147. class Revision extends Model
  148. {
  149. public $timestamps = false;
  150. protected $guarded = [];
  151. }
  152. class User extends Model
  153. {
  154. public $timestamps = false;
  155. public function posts()
  156. {
  157. return $this->hasMany(Post::class);
  158. }
  159. }