1、问题:在模型关联中常常会疑惑例如:$user->addresses () 和 $user->addresses 的区别.
2、归纳与总结:
模型:(一对多) 一个用户多个收货地址
// 用户
class User
{
public function addresses()
{
return $this->hasMany(UserAddress::class);
}
}
// 收货地址
class UserAddress
{
public function user()
{
return $this->belongsTo(User::class);
}
}
问题:下面 $what1 和 $what2 的区别
$user = App\Models\User::find(1) //App\Models\User
$what1 = $user->addresses() // Illuminate\Database\Eloquent\Relations\HasMany
$what2 = $user->addresses // Illuminate\Database\Eloquent\Collection
要知道上述用法的区别,就要认识上述的三个类:
- App\Models\User
这个就是常见的模型类,假如我们要访问用户的名称就可以通用 $user->name 这样访问属性的方式来简单访问。因为 name 这个这个 $user 实例的一个属性 - Illuminate\Database\Eloquent\Relations\HasMany
看名称我们就知道,这是个 Eloquent 中处理一对多的类;查看源码 (下图) 可以看到,HasMany 最终是实现了抽象父类 Relation,
而 Relation 返回的是一个 叫做 Builder 的实例。 Builder(构造器) 可以简单的理解为,帮你组装 sql 的一个工具类。
所以对于 $user->addresses () 只是一个构造器。这个构造器并不能直接的帮我们获取到 “用户所有的收货地址” 的数据。
所以我们可以进行以下操作获取数据:
$user_addresses = $user->addresses //获取用户下所有的收货地址
$user_addresses2 = $user->addresses()->get() // 和上面异曲同工
复习与延申思考
从收货地址角度出发,我们再看一看下列每个变量是什么类型的数据。
// App\Models\UserAddress;
$user_address = App\Models\UserAddress::find(1);
//Illuminate\Database\Eloquent\Relations\BelongsTo;
$data1 = $user_address->user();
// App\Models\User;
$data2 = $user_address->user;
// Illuminate\Database\Eloquent\Collection 即使items只有一个模型;
$data3 = $user_address->user()->get();
// 如果用户的id为1时--App\Models\User; 不为1时--null
$data4 = $user_address->user()->get()->find(1);
// 如果用户的id为1时--显示用户的名称即name属性; 不为1时系统报错。
$data5 = $user_address->user()->get()->find(1)->name;
// App\Models\User;
$data6 = $user_address->user()->first();
// 参照$data5
$data7 = $user_address->user()->first()->name;
// 参照$data5
$data8 = $user_address->user->name;
引用
https://learnku.com/articles/44934