以最简单的代码为例引出具体内容
模型配置一对一关系
具体使用方法看官方文档
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Test;
class User extends Authenticatable
{
use Notifiable,SoftDeletes;
/**
* 获得与用户关联的电话记录。
*/
public function phone()
{
return $this->hasOne(Test::class);
}
}
控制器调用
$user = User::find(2)->phone;
根据分析可知User::find(2)
返回是Use
类,调用一个不存在的属性就会触发抽象类Model
下的__get
方法
/**
* Dynamically retrieve attributes on the model.
*
* @param string $key
* @return mixed
*/
public function __get($key)
{
return $this->getAttribute($key);
}
getAttribute
方法是在trait
HasAttributes
下
/**
* Get an attribute from the model.
*
* @param string $key
* @return mixed
*/
public function getAttribute($key)
{
if (! $key) {
return;
}
// If the attribute exists in the attribute array or has a "get" mutator we will
// get the attribute's value. Otherwise, we will proceed as if the developers
// are asking for a relationship's value. This covers both types of values.
if (array_key_exists($key, $this->attributes) ||
$this->hasGetMutator($key)) {
return $this->getAttributeValue($key);
}
// Here we will determine if the model base class itself contains this given key
// since we don't want to treat any of those methods as relationships because
// they are all intended as helper methods and none of these are relations.
if (method_exists(self::class, $key)) {
return;
}
return $this->getRelationValue($key);
}
根据判断会调用getRelationshipFromMethod方法
/**
* Get a relationship value from a method.
*
* @param string $method
* @return mixed
*
* @throws \LogicException
*/
protected function getRelationshipFromMethod($method)
{
$relation = $this->$method();
if (! $relation instanceof Relation) {
throw new LogicException(get_class($this).'::'.$method.' must return a relationship instance.');
}
return tap($relation->getResults(), function ($results) use ($method) {
$this->setRelation($method, $results);
});
}
返回的是Test类,重点是$relation =
t
h
i
s
−
>
this->
this−>method();代码的执行 $relation是HasOne 的实例,在实例化的过程中会调用
$this->addConstraints()方法
namespace Illuminate\Database\Eloquent\Relations;
use Closure;
use Illuminate\Support\Arr;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Eloquent\Collection;
/**
* @mixin \Illuminate\Database\Eloquent\Builder
*/
abstract class Relation
{
use Macroable {
__call as macroCall;
}
/**
* The Eloquent query builder instance.
*
* @var \Illuminate\Database\Eloquent\Builder
*/
protected $query;
/**
* The parent model instance.
*
* @var \Illuminate\Database\Eloquent\Model
*/
protected $parent;
/**
* The related model instance.
*
* @var \Illuminate\Database\Eloquent\Model
*/
protected $related;
/**
* Indicates if the relation is adding constraints.
*
* @var bool
*/
protected static $constraints = true;
/**
* An array to map class names to their morph names in database.
*
* @var array
*/
public static $morphMap = [];
/**
* Create a new relation instance.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @return void
*/
public function __construct(Builder $query, Model $parent)
{
$this->query = $query;
$this->parent = $parent;
$this->related = $query->getModel();
$this->addConstraints();
}
addConstraints
方法具体的实现在抽象类HasOneOrMany
下
/**
* Set the base constraints on the relation query.
*
* @return void
*/
public function addConstraints()
{
if (static::$constraints) {
$this->query->where($this->foreignKey, '=', $this->getParentKey());
$this->query->whereNotNull($this->foreignKey);
}
}
这边就是构造对象的查询语句的方法
- 终
如有不对的地方请及时指正