2016-08-09 9 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のインスタンスを返し、2番目のインスタンスはBelongsToManyのインスタンスを返します。

Collectionは、関連するオブジェクトのコレクション(実際は?)であり、BelongsToManyはリレーション自体です。したがって、メソッドを呼び出すことで(そして魔法のプロパティではなく)、データベースを照会しています。

更新

私は最後の質問を取得できませんでした、申し訳ありません。 初めて$role->permissions(マジックプロパティ)に電話すると、eager loadedではない場合、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(); 

あなたが見ることができるように、最初の例では、あなたが唯一のクエリを作成し、異なった結果をフィルタリングします。 2番目の例では、2つのクエリを行います。最初の方が明らかに効率的です。

同じ実行中にサブセットのみが必要な場合は、状況が変わります。ここでは、eager loadingを使用している:

$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はるかに小さい、と我々はまた、同じ操作を複数回行っています。もちろん、それほど効率的ではありません。

関連する問題