你基本上是对的。呼叫$role->permissions
和$role->permissions()
之间的区别在于第一个返回Collection
的实例,而第二个返回BelongsToMany
的实例。
Collection
是相关对象的集合(真的?),BelongsToMany
是关系本身。所以是的,通过调用方法(而不是魔术属性),您正在查询数据库。
更新
我没有得到最后一个问题,对不起。 您第一次致电$role->permissions
(魔法财产)时,Laravel获取与$role
相关的所有权限,如果它们不是eager loaded。如果您只需要这些权限的子集,则可以使用任何魔术属性和方法来过滤它们。让我举一些例子。
$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();
如果你取什么相关的所有对象,但需要一个子集:这里我们使用eager loading?
$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,同时我们也在做同样的操作多次。当然效率较低。