HasRelationships.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. <?php
  2. namespace Illuminate\Database\Eloquent\Concerns;
  3. use Illuminate\Support\Arr;
  4. use Illuminate\Support\Str;
  5. use Illuminate\Database\Eloquent\Model;
  6. use Illuminate\Database\Eloquent\Builder;
  7. use Illuminate\Database\Eloquent\Collection;
  8. use Illuminate\Database\Eloquent\Relations\HasOne;
  9. use Illuminate\Database\Eloquent\Relations\HasMany;
  10. use Illuminate\Database\Eloquent\Relations\MorphTo;
  11. use Illuminate\Database\Eloquent\Relations\MorphOne;
  12. use Illuminate\Database\Eloquent\Relations\Relation;
  13. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  14. use Illuminate\Database\Eloquent\Relations\MorphMany;
  15. use Illuminate\Database\Eloquent\Relations\MorphToMany;
  16. use Illuminate\Database\Eloquent\Relations\BelongsToMany;
  17. use Illuminate\Database\Eloquent\Relations\HasManyThrough;
  18. trait HasRelationships
  19. {
  20. /**
  21. * The loaded relationships for the model.
  22. *
  23. * @var array
  24. */
  25. protected $relations = [];
  26. /**
  27. * The relationships that should be touched on save.
  28. *
  29. * @var array
  30. */
  31. protected $touches = [];
  32. /**
  33. * The many to many relationship methods.
  34. *
  35. * @var array
  36. */
  37. public static $manyMethods = [
  38. 'belongsToMany', 'morphToMany', 'morphedByMany',
  39. 'guessBelongsToManyRelation', 'findFirstMethodThatIsntRelation',
  40. ];
  41. /**
  42. * Define a one-to-one relationship.
  43. *
  44. * @param string $related
  45. * @param string $foreignKey
  46. * @param string $localKey
  47. * @return \Illuminate\Database\Eloquent\Relations\HasOne
  48. */
  49. public function hasOne($related, $foreignKey = null, $localKey = null)
  50. {
  51. $instance = $this->newRelatedInstance($related);
  52. $foreignKey = $foreignKey ?: $this->getForeignKey();
  53. $localKey = $localKey ?: $this->getKeyName();
  54. return $this->newHasOne($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey);
  55. }
  56. /**
  57. * Instantiate a new HasOne relationship.
  58. *
  59. * @param \Illuminate\Database\Eloquent\Builder $query
  60. * @param \Illuminate\Database\Eloquent\Model $parent
  61. * @param string $foreignKey
  62. * @param string $localKey
  63. * @return \Illuminate\Database\Eloquent\Relations\HasOne
  64. */
  65. protected function newHasOne(Builder $query, Model $parent, $foreignKey, $localKey)
  66. {
  67. return new HasOne($query, $parent, $foreignKey, $localKey);
  68. }
  69. /**
  70. * Define a polymorphic one-to-one relationship.
  71. *
  72. * @param string $related
  73. * @param string $name
  74. * @param string $type
  75. * @param string $id
  76. * @param string $localKey
  77. * @return \Illuminate\Database\Eloquent\Relations\MorphOne
  78. */
  79. public function morphOne($related, $name, $type = null, $id = null, $localKey = null)
  80. {
  81. $instance = $this->newRelatedInstance($related);
  82. list($type, $id) = $this->getMorphs($name, $type, $id);
  83. $table = $instance->getTable();
  84. $localKey = $localKey ?: $this->getKeyName();
  85. return $this->newMorphOne($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
  86. }
  87. /**
  88. * Instantiate a new MorphOne relationship.
  89. *
  90. * @param \Illuminate\Database\Eloquent\Builder $query
  91. * @param \Illuminate\Database\Eloquent\Model $parent
  92. * @param string $type
  93. * @param string $id
  94. * @param string $localKey
  95. * @return \Illuminate\Database\Eloquent\Relations\MorphOne
  96. */
  97. protected function newMorphOne(Builder $query, Model $parent, $type, $id, $localKey)
  98. {
  99. return new MorphOne($query, $parent, $type, $id, $localKey);
  100. }
  101. /**
  102. * Define an inverse one-to-one or many relationship.
  103. *
  104. * @param string $related
  105. * @param string $foreignKey
  106. * @param string $ownerKey
  107. * @param string $relation
  108. * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
  109. */
  110. public function belongsTo($related, $foreignKey = null, $ownerKey = null, $relation = null)
  111. {
  112. // If no relation name was given, we will use this debug backtrace to extract
  113. // the calling method's name and use that as the relationship name as most
  114. // of the time this will be what we desire to use for the relationships.
  115. if (is_null($relation)) {
  116. $relation = $this->guessBelongsToRelation();
  117. }
  118. $instance = $this->newRelatedInstance($related);
  119. // If no foreign key was supplied, we can use a backtrace to guess the proper
  120. // foreign key name by using the name of the relationship function, which
  121. // when combined with an "_id" should conventionally match the columns.
  122. if (is_null($foreignKey)) {
  123. $foreignKey = Str::snake($relation).'_'.$instance->getKeyName();
  124. }
  125. // Once we have the foreign key names, we'll just create a new Eloquent query
  126. // for the related models and returns the relationship instance which will
  127. // actually be responsible for retrieving and hydrating every relations.
  128. $ownerKey = $ownerKey ?: $instance->getKeyName();
  129. return $this->newBelongsTo(
  130. $instance->newQuery(), $this, $foreignKey, $ownerKey, $relation
  131. );
  132. }
  133. /**
  134. * Instantiate a new BelongsTo relationship.
  135. *
  136. * @param \Illuminate\Database\Eloquent\Builder $query
  137. * @param \Illuminate\Database\Eloquent\Model $child
  138. * @param string $foreignKey
  139. * @param string $ownerKey
  140. * @param string $relation
  141. * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
  142. */
  143. protected function newBelongsTo(Builder $query, Model $child, $foreignKey, $ownerKey, $relation)
  144. {
  145. return new BelongsTo($query, $child, $foreignKey, $ownerKey, $relation);
  146. }
  147. /**
  148. * Define a polymorphic, inverse one-to-one or many relationship.
  149. *
  150. * @param string $name
  151. * @param string $type
  152. * @param string $id
  153. * @return \Illuminate\Database\Eloquent\Relations\MorphTo
  154. */
  155. public function morphTo($name = null, $type = null, $id = null)
  156. {
  157. // If no name is provided, we will use the backtrace to get the function name
  158. // since that is most likely the name of the polymorphic interface. We can
  159. // use that to get both the class and foreign key that will be utilized.
  160. $name = $name ?: $this->guessBelongsToRelation();
  161. list($type, $id) = $this->getMorphs(
  162. Str::snake($name), $type, $id
  163. );
  164. // If the type value is null it is probably safe to assume we're eager loading
  165. // the relationship. In this case we'll just pass in a dummy query where we
  166. // need to remove any eager loads that may already be defined on a model.
  167. return empty($class = $this->{$type})
  168. ? $this->morphEagerTo($name, $type, $id)
  169. : $this->morphInstanceTo($class, $name, $type, $id);
  170. }
  171. /**
  172. * Define a polymorphic, inverse one-to-one or many relationship.
  173. *
  174. * @param string $name
  175. * @param string $type
  176. * @param string $id
  177. * @return \Illuminate\Database\Eloquent\Relations\MorphTo
  178. */
  179. protected function morphEagerTo($name, $type, $id)
  180. {
  181. return $this->newMorphTo(
  182. $this->newQuery()->setEagerLoads([]), $this, $id, null, $type, $name
  183. );
  184. }
  185. /**
  186. * Define a polymorphic, inverse one-to-one or many relationship.
  187. *
  188. * @param string $target
  189. * @param string $name
  190. * @param string $type
  191. * @param string $id
  192. * @return \Illuminate\Database\Eloquent\Relations\MorphTo
  193. */
  194. protected function morphInstanceTo($target, $name, $type, $id)
  195. {
  196. $instance = $this->newRelatedInstance(
  197. static::getActualClassNameForMorph($target)
  198. );
  199. return $this->newMorphTo(
  200. $instance->newQuery(), $this, $id, $instance->getKeyName(), $type, $name
  201. );
  202. }
  203. /**
  204. * Instantiate a new MorphTo relationship.
  205. *
  206. * @param \Illuminate\Database\Eloquent\Builder $query
  207. * @param \Illuminate\Database\Eloquent\Model $parent
  208. * @param string $foreignKey
  209. * @param string $ownerKey
  210. * @param string $type
  211. * @param string $relation
  212. * @return \Illuminate\Database\Eloquent\Relations\MorphTo
  213. */
  214. protected function newMorphTo(Builder $query, Model $parent, $foreignKey, $ownerKey, $type, $relation)
  215. {
  216. return new MorphTo($query, $parent, $foreignKey, $ownerKey, $type, $relation);
  217. }
  218. /**
  219. * Retrieve the actual class name for a given morph class.
  220. *
  221. * @param string $class
  222. * @return string
  223. */
  224. public static function getActualClassNameForMorph($class)
  225. {
  226. return Arr::get(Relation::morphMap() ?: [], $class, $class);
  227. }
  228. /**
  229. * Guess the "belongs to" relationship name.
  230. *
  231. * @return string
  232. */
  233. protected function guessBelongsToRelation()
  234. {
  235. list($one, $two, $caller) = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
  236. return $caller['function'];
  237. }
  238. /**
  239. * Define a one-to-many relationship.
  240. *
  241. * @param string $related
  242. * @param string $foreignKey
  243. * @param string $localKey
  244. * @return \Illuminate\Database\Eloquent\Relations\HasMany
  245. */
  246. public function hasMany($related, $foreignKey = null, $localKey = null)
  247. {
  248. $instance = $this->newRelatedInstance($related);
  249. $foreignKey = $foreignKey ?: $this->getForeignKey();
  250. $localKey = $localKey ?: $this->getKeyName();
  251. return $this->newHasMany(
  252. $instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey
  253. );
  254. }
  255. /**
  256. * Instantiate a new HasMany relationship.
  257. *
  258. * @param \Illuminate\Database\Eloquent\Builder $query
  259. * @param \Illuminate\Database\Eloquent\Model $parent
  260. * @param string $foreignKey
  261. * @param string $localKey
  262. * @return \Illuminate\Database\Eloquent\Relations\HasMany
  263. */
  264. protected function newHasMany(Builder $query, Model $parent, $foreignKey, $localKey)
  265. {
  266. return new HasMany($query, $parent, $foreignKey, $localKey);
  267. }
  268. /**
  269. * Define a has-many-through relationship.
  270. *
  271. * @param string $related
  272. * @param string $through
  273. * @param string|null $firstKey
  274. * @param string|null $secondKey
  275. * @param string|null $localKey
  276. * @param string|null $secondLocalKey
  277. * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
  278. */
  279. public function hasManyThrough($related, $through, $firstKey = null, $secondKey = null, $localKey = null, $secondLocalKey = null)
  280. {
  281. $through = new $through;
  282. $firstKey = $firstKey ?: $this->getForeignKey();
  283. $secondKey = $secondKey ?: $through->getForeignKey();
  284. return $this->newHasManyThrough(
  285. $this->newRelatedInstance($related)->newQuery(), $this, $through,
  286. $firstKey, $secondKey, $localKey ?: $this->getKeyName(),
  287. $secondLocalKey ?: $through->getKeyName()
  288. );
  289. }
  290. /**
  291. * Instantiate a new HasManyThrough relationship.
  292. *
  293. * @param \Illuminate\Database\Eloquent\Builder $query
  294. * @param \Illuminate\Database\Eloquent\Model $farParent
  295. * @param \Illuminate\Database\Eloquent\Model $throughParent
  296. * @param string $firstKey
  297. * @param string $secondKey
  298. * @param string $localKey
  299. * @param string $secondLocalKey
  300. * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
  301. */
  302. protected function newHasManyThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey)
  303. {
  304. return new HasManyThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
  305. }
  306. /**
  307. * Define a polymorphic one-to-many relationship.
  308. *
  309. * @param string $related
  310. * @param string $name
  311. * @param string $type
  312. * @param string $id
  313. * @param string $localKey
  314. * @return \Illuminate\Database\Eloquent\Relations\MorphMany
  315. */
  316. public function morphMany($related, $name, $type = null, $id = null, $localKey = null)
  317. {
  318. $instance = $this->newRelatedInstance($related);
  319. // Here we will gather up the morph type and ID for the relationship so that we
  320. // can properly query the intermediate table of a relation. Finally, we will
  321. // get the table and create the relationship instances for the developers.
  322. list($type, $id) = $this->getMorphs($name, $type, $id);
  323. $table = $instance->getTable();
  324. $localKey = $localKey ?: $this->getKeyName();
  325. return $this->newMorphMany($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
  326. }
  327. /**
  328. * Instantiate a new MorphMany relationship.
  329. *
  330. * @param \Illuminate\Database\Eloquent\Builder $query
  331. * @param \Illuminate\Database\Eloquent\Model $parent
  332. * @param string $type
  333. * @param string $id
  334. * @param string $localKey
  335. * @return \Illuminate\Database\Eloquent\Relations\MorphMany
  336. */
  337. protected function newMorphMany(Builder $query, Model $parent, $type, $id, $localKey)
  338. {
  339. return new MorphMany($query, $parent, $type, $id, $localKey);
  340. }
  341. /**
  342. * Define a many-to-many relationship.
  343. *
  344. * @param string $related
  345. * @param string $table
  346. * @param string $foreignPivotKey
  347. * @param string $relatedPivotKey
  348. * @param string $parentKey
  349. * @param string $relatedKey
  350. * @param string $relation
  351. * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
  352. */
  353. public function belongsToMany($related, $table = null, $foreignPivotKey = null, $relatedPivotKey = null,
  354. $parentKey = null, $relatedKey = null, $relation = null)
  355. {
  356. // If no relationship name was passed, we will pull backtraces to get the
  357. // name of the calling function. We will use that function name as the
  358. // title of this relation since that is a great convention to apply.
  359. if (is_null($relation)) {
  360. $relation = $this->guessBelongsToManyRelation();
  361. }
  362. // First, we'll need to determine the foreign key and "other key" for the
  363. // relationship. Once we have determined the keys we'll make the query
  364. // instances as well as the relationship instances we need for this.
  365. $instance = $this->newRelatedInstance($related);
  366. $foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();
  367. $relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();
  368. // If no table name was provided, we can guess it by concatenating the two
  369. // models using underscores in alphabetical order. The two model names
  370. // are transformed to snake case from their default CamelCase also.
  371. if (is_null($table)) {
  372. $table = $this->joiningTable($related);
  373. }
  374. return $this->newBelongsToMany(
  375. $instance->newQuery(), $this, $table, $foreignPivotKey,
  376. $relatedPivotKey, $parentKey ?: $this->getKeyName(),
  377. $relatedKey ?: $instance->getKeyName(), $relation
  378. );
  379. }
  380. /**
  381. * Instantiate a new BelongsToMany relationship.
  382. *
  383. * @param \Illuminate\Database\Eloquent\Builder $query
  384. * @param \Illuminate\Database\Eloquent\Model $parent
  385. * @param string $table
  386. * @param string $foreignPivotKey
  387. * @param string $relatedPivotKey
  388. * @param string $parentKey
  389. * @param string $relatedKey
  390. * @param string $relationName
  391. * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
  392. */
  393. protected function newBelongsToMany(Builder $query, Model $parent, $table, $foreignPivotKey, $relatedPivotKey,
  394. $parentKey, $relatedKey, $relationName = null)
  395. {
  396. return new BelongsToMany($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName);
  397. }
  398. /**
  399. * Define a polymorphic many-to-many relationship.
  400. *
  401. * @param string $related
  402. * @param string $name
  403. * @param string $table
  404. * @param string $foreignPivotKey
  405. * @param string $relatedPivotKey
  406. * @param string $parentKey
  407. * @param string $relatedKey
  408. * @param bool $inverse
  409. * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
  410. */
  411. public function morphToMany($related, $name, $table = null, $foreignPivotKey = null,
  412. $relatedPivotKey = null, $parentKey = null,
  413. $relatedKey = null, $inverse = false)
  414. {
  415. $caller = $this->guessBelongsToManyRelation();
  416. // First, we will need to determine the foreign key and "other key" for the
  417. // relationship. Once we have determined the keys we will make the query
  418. // instances, as well as the relationship instances we need for these.
  419. $instance = $this->newRelatedInstance($related);
  420. $foreignPivotKey = $foreignPivotKey ?: $name.'_id';
  421. $relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();
  422. // Now we're ready to create a new query builder for this related model and
  423. // the relationship instances for this relation. This relations will set
  424. // appropriate query constraints then entirely manages the hydrations.
  425. $table = $table ?: Str::plural($name);
  426. return $this->newMorphToMany(
  427. $instance->newQuery(), $this, $name, $table,
  428. $foreignPivotKey, $relatedPivotKey, $parentKey ?: $this->getKeyName(),
  429. $relatedKey ?: $instance->getKeyName(), $caller, $inverse
  430. );
  431. }
  432. /**
  433. * Instantiate a new HasManyThrough relationship.
  434. *
  435. * @param \Illuminate\Database\Eloquent\Builder $query
  436. * @param \Illuminate\Database\Eloquent\Model $parent
  437. * @param string $name
  438. * @param string $table
  439. * @param string $foreignPivotKey
  440. * @param string $relatedPivotKey
  441. * @param string $parentKey
  442. * @param string $relatedKey
  443. * @param string $relationName
  444. * @param bool $inverse
  445. * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
  446. */
  447. protected function newMorphToMany(Builder $query, Model $parent, $name, $table, $foreignPivotKey,
  448. $relatedPivotKey, $parentKey, $relatedKey,
  449. $relationName = null, $inverse = false)
  450. {
  451. return new MorphToMany($query, $parent, $name, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey,
  452. $relationName, $inverse);
  453. }
  454. /**
  455. * Define a polymorphic, inverse many-to-many relationship.
  456. *
  457. * @param string $related
  458. * @param string $name
  459. * @param string $table
  460. * @param string $foreignPivotKey
  461. * @param string $relatedPivotKey
  462. * @param string $parentKey
  463. * @param string $relatedKey
  464. * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
  465. */
  466. public function morphedByMany($related, $name, $table = null, $foreignPivotKey = null,
  467. $relatedPivotKey = null, $parentKey = null, $relatedKey = null)
  468. {
  469. $foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();
  470. // For the inverse of the polymorphic many-to-many relations, we will change
  471. // the way we determine the foreign and other keys, as it is the opposite
  472. // of the morph-to-many method since we're figuring out these inverses.
  473. $relatedPivotKey = $relatedPivotKey ?: $name.'_id';
  474. return $this->morphToMany(
  475. $related, $name, $table, $foreignPivotKey,
  476. $relatedPivotKey, $parentKey, $relatedKey, true
  477. );
  478. }
  479. /**
  480. * Get the relationship name of the belongs to many.
  481. *
  482. * @return string
  483. */
  484. protected function guessBelongsToManyRelation()
  485. {
  486. $caller = Arr::first(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), function ($trace) {
  487. return ! in_array($trace['function'], Model::$manyMethods);
  488. });
  489. return ! is_null($caller) ? $caller['function'] : null;
  490. }
  491. /**
  492. * Get the joining table name for a many-to-many relation.
  493. *
  494. * @param string $related
  495. * @return string
  496. */
  497. public function joiningTable($related)
  498. {
  499. // The joining table name, by convention, is simply the snake cased models
  500. // sorted alphabetically and concatenated with an underscore, so we can
  501. // just sort the models and join them together to get the table name.
  502. $models = [
  503. Str::snake(class_basename($related)),
  504. Str::snake(class_basename($this)),
  505. ];
  506. // Now that we have the model names in an array we can just sort them and
  507. // use the implode function to join them together with an underscores,
  508. // which is typically used by convention within the database system.
  509. sort($models);
  510. return strtolower(implode('_', $models));
  511. }
  512. /**
  513. * Determine if the model touches a given relation.
  514. *
  515. * @param string $relation
  516. * @return bool
  517. */
  518. public function touches($relation)
  519. {
  520. return in_array($relation, $this->touches);
  521. }
  522. /**
  523. * Touch the owning relations of the model.
  524. *
  525. * @return void
  526. */
  527. public function touchOwners()
  528. {
  529. foreach ($this->touches as $relation) {
  530. $this->$relation()->touch();
  531. if ($this->$relation instanceof self) {
  532. $this->$relation->fireModelEvent('saved', false);
  533. $this->$relation->touchOwners();
  534. } elseif ($this->$relation instanceof Collection) {
  535. $this->$relation->each(function (Model $relation) {
  536. $relation->touchOwners();
  537. });
  538. }
  539. }
  540. }
  541. /**
  542. * Get the polymorphic relationship columns.
  543. *
  544. * @param string $name
  545. * @param string $type
  546. * @param string $id
  547. * @return array
  548. */
  549. protected function getMorphs($name, $type, $id)
  550. {
  551. return [$type ?: $name.'_type', $id ?: $name.'_id'];
  552. }
  553. /**
  554. * Get the class name for polymorphic relations.
  555. *
  556. * @return string
  557. */
  558. public function getMorphClass()
  559. {
  560. $morphMap = Relation::morphMap();
  561. if (! empty($morphMap) && in_array(static::class, $morphMap)) {
  562. return array_search(static::class, $morphMap, true);
  563. }
  564. return static::class;
  565. }
  566. /**
  567. * Create a new model instance for a related model.
  568. *
  569. * @param string $class
  570. * @return mixed
  571. */
  572. protected function newRelatedInstance($class)
  573. {
  574. return tap(new $class, function ($instance) {
  575. if (! $instance->getConnectionName()) {
  576. $instance->setConnection($this->connection);
  577. }
  578. });
  579. }
  580. /**
  581. * Get all the loaded relations for the instance.
  582. *
  583. * @return array
  584. */
  585. public function getRelations()
  586. {
  587. return $this->relations;
  588. }
  589. /**
  590. * Get a specified relationship.
  591. *
  592. * @param string $relation
  593. * @return mixed
  594. */
  595. public function getRelation($relation)
  596. {
  597. return $this->relations[$relation];
  598. }
  599. /**
  600. * Determine if the given relation is loaded.
  601. *
  602. * @param string $key
  603. * @return bool
  604. */
  605. public function relationLoaded($key)
  606. {
  607. return array_key_exists($key, $this->relations);
  608. }
  609. /**
  610. * Set the specific relationship in the model.
  611. *
  612. * @param string $relation
  613. * @param mixed $value
  614. * @return $this
  615. */
  616. public function setRelation($relation, $value)
  617. {
  618. $this->relations[$relation] = $value;
  619. return $this;
  620. }
  621. /**
  622. * Set the entire relations array on the model.
  623. *
  624. * @param array $relations
  625. * @return $this
  626. */
  627. public function setRelations(array $relations)
  628. {
  629. $this->relations = $relations;
  630. return $this;
  631. }
  632. /**
  633. * Get the relationships that are touched on save.
  634. *
  635. * @return array
  636. */
  637. public function getTouchedRelations()
  638. {
  639. return $this->touches;
  640. }
  641. /**
  642. * Set the relationships that are touched on save.
  643. *
  644. * @param array $touches
  645. * @return $this
  646. */
  647. public function setTouchedRelations(array $touches)
  648. {
  649. $this->touches = $touches;
  650. return $this;
  651. }
  652. }