HasOne.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <?php
  2. namespace Illuminate\Database\Eloquent\Relations;
  3. use Illuminate\Contracts\Database\Eloquent\SupportsPartialRelations;
  4. use Illuminate\Database\Eloquent\Builder;
  5. use Illuminate\Database\Eloquent\Collection;
  6. use Illuminate\Database\Eloquent\Model;
  7. use Illuminate\Database\Eloquent\Relations\Concerns\CanBeOneOfMany;
  8. use Illuminate\Database\Eloquent\Relations\Concerns\ComparesRelatedModels;
  9. use Illuminate\Database\Eloquent\Relations\Concerns\SupportsDefaultModels;
  10. use Illuminate\Database\Query\JoinClause;
  11. class HasOne extends HasOneOrMany implements SupportsPartialRelations
  12. {
  13. use ComparesRelatedModels, CanBeOneOfMany, SupportsDefaultModels;
  14. /**
  15. * Get the results of the relationship.
  16. *
  17. * @return mixed
  18. */
  19. public function getResults()
  20. {
  21. if (is_null($this->getParentKey())) {
  22. return $this->getDefaultFor($this->parent);
  23. }
  24. return $this->query->first() ?: $this->getDefaultFor($this->parent);
  25. }
  26. /**
  27. * Initialize the relation on a set of models.
  28. *
  29. * @param array $models
  30. * @param string $relation
  31. * @return array
  32. */
  33. public function initRelation(array $models, $relation)
  34. {
  35. foreach ($models as $model) {
  36. $model->setRelation($relation, $this->getDefaultFor($model));
  37. }
  38. return $models;
  39. }
  40. /**
  41. * Match the eagerly loaded results to their parents.
  42. *
  43. * @param array $models
  44. * @param \Illuminate\Database\Eloquent\Collection $results
  45. * @param string $relation
  46. * @return array
  47. */
  48. public function match(array $models, Collection $results, $relation)
  49. {
  50. return $this->matchOne($models, $results, $relation);
  51. }
  52. /**
  53. * Add the constraints for an internal relationship existence query.
  54. *
  55. * Essentially, these queries compare on column names like "whereColumn".
  56. *
  57. * @param \Illuminate\Database\Eloquent\Builder $query
  58. * @param \Illuminate\Database\Eloquent\Builder $parentQuery
  59. * @param array|mixed $columns
  60. * @return \Illuminate\Database\Eloquent\Builder
  61. */
  62. public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
  63. {
  64. if ($this->isOneOfMany()) {
  65. $this->mergeOneOfManyJoinsTo($query);
  66. }
  67. return parent::getRelationExistenceQuery($query, $parentQuery, $columns);
  68. }
  69. /**
  70. * Add constraints for inner join subselect for one of many relationships.
  71. *
  72. * @param \Illuminate\Database\Eloquent\Builder $query
  73. * @param string|null $column
  74. * @param string|null $aggregate
  75. * @return void
  76. */
  77. public function addOneOfManySubQueryConstraints(Builder $query, $column = null, $aggregate = null)
  78. {
  79. $query->addSelect($this->foreignKey);
  80. }
  81. /**
  82. * Get the columns that should be selected by the one of many subquery.
  83. *
  84. * @return array|string
  85. */
  86. public function getOneOfManySubQuerySelectColumns()
  87. {
  88. return $this->foreignKey;
  89. }
  90. /**
  91. * Add join query constraints for one of many relationships.
  92. *
  93. * @param \Illuminate\Database\Query\JoinClause $join
  94. * @return void
  95. */
  96. public function addOneOfManyJoinSubQueryConstraints(JoinClause $join)
  97. {
  98. $join->on($this->qualifySubSelectColumn($this->foreignKey), '=', $this->qualifyRelatedColumn($this->foreignKey));
  99. }
  100. /**
  101. * Make a new related instance for the given model.
  102. *
  103. * @param \Illuminate\Database\Eloquent\Model $parent
  104. * @return \Illuminate\Database\Eloquent\Model
  105. */
  106. public function newRelatedInstanceFor(Model $parent)
  107. {
  108. return $this->related->newInstance()->setAttribute(
  109. $this->getForeignKeyName(), $parent->{$this->localKey}
  110. );
  111. }
  112. /**
  113. * Get the value of the model's foreign key.
  114. *
  115. * @param \Illuminate\Database\Eloquent\Model $model
  116. * @return mixed
  117. */
  118. protected function getRelatedKeyFrom(Model $model)
  119. {
  120. return $model->getAttribute($this->getForeignKeyName());
  121. }
  122. }