你基本上是对的。$role->permissions
调用和之间的区别在于$role->permissions()
,第一个返回 的实例Collection
,而第二个返回 的实例BelongsToMany
。
Collection
是相关对象的集合(真的吗?)并且BelongsToMany
是关系本身。所以是的,通过调用方法(而不是魔法属性),您正在查询数据库。
更新
最后一个问题我没听懂,抱歉。第一次调用$role->permissions
(magic property) 时,Laravel 会获取与 关联的所有权限$role
,如果它们不是预先加载的。如果您只需要这些权限的一个子集,您可以使用任何魔法属性和方法来过滤它们。让我举几个例子。
$role = Role::first();
// Fetch all the permissions and count a subset.
$role->permissions->where('code', 'global.test')->count();
// Count another subset.
$role->permissions->where('code', 'another.test')->count();
可以使用以下方法完成相同的操作:
$role = Role::first();
// Fetch a subset of the permissions and count it.
$role->permissions()->where('code', 'global.test')->count();
// Fetch another subset and count it.
$role->permissions()->where('code', 'another.test')->count();
如您所见,在第一个示例中,您只进行一次查询并以不同方式过滤结果。在第二个示例中,您进行了两个查询。第一个显然更有效。
但是,如果您在同一执行期间只需要一个子集,情况就会发生变化。这里我们使用急切加载:
$role = Role::with('permissions', function($query) {
// Here we filter the related permissions.
$query->where('code', 'global.test');
})->first();
// We have what we want. No need to filter the collection.
$role->permissions->count();
// Let's do something else with this subset.
$role->permissions->all();
如果您获取所有相关对象,但只需要该子集怎么办?
$role = Role::first();
// Filter the collection to count the needed subset.
$role->permissions->where('code', 'global.test')->count();
// Filter the collection to get the needed subset.
$role->permissions->where('code', 'global.test')->all();
如您所见,在第二个示例中,我们的DRY少得多,而且我们还多次执行相同的操作。当然,效率较低。