Правильно ли я понял, что когда я запрашиваю коллекцию 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()
В общем, $ Ролевые> разрешения — работа с извлеченными результатами «в автономном режиме», но $> Разрешения ролевых () — запрос к базе данных
Какой способ в целом более эффективен и когда?
Ты в принципе прав. Разница между звонками $role->permissions
а также $role->permissions()
является то, что первый возвращает экземпляр Collection
в то время как второй возвращает экземпляр BelongsToMany
,
Collection
коллекция (действительно?) связанных объектов и BelongsToMany
это само отношение. Так что да, вызывая метод (а не магическое свойство), вы запрашиваете базу данных.
Я не получил последний вопрос, извините.
Первый раз звонишь $role->permissions
(магическое свойство), 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, и мы также делаем одну и ту же операцию несколько раз. Менее эффективно, конечно.
Других решений пока нет …