2016-08-09 143 views
1

我是否正确地得知它,当我查询Laravel集合时,它不查询数据库,但对已获取的内容执行查询?查询Laravel中的集合

例如,我有一个返回集合的关系:

public function permissions() 
{ 
    return $this->belongsToMany(Permission::class, RolePermission::getModelTable(), 'role_id', 'permission_id'); 
} 

执行以下代码查询数据库或将其与使用PHP设施收集的作品?

$role->permissions->where('code','global.test')->count() 

而且,据我了解,如果我查询,则关系数据库将被查询,而不是与那些已经获取的结果工作:

$role->permissions()->where('code','global.test')->count() 

所以基本上,$角色 - >权限 - 与获取的成果“离线”的工作,但$基于角色>权限() - 查询数据库

什么方式通常更高效,更当是什么?

回答

2

你基本上是对的。呼叫$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,同时我们也在做同样的操作多次。当然效率较低。