あなたは基本的に正しいです。と の呼び出しの違いは、最初の呼び出し$role->permissions
では のインスタンスが返されるのに対して、2 番目の呼び出しでは のインスタンスが返されることです。$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();
ご覧のとおり、最初の例では、クエリを 1 つだけ作成し、結果を別の方法でフィルター処理しています。2 番目の例では、2 つのクエリを作成します。最初のものは明らかにより効率的です。
ただし、同じ実行中にサブセットのみが必要な場合は、状況が変わります。ここでは熱心な読み込みを使用しています:
$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();
ご覧のとおり、2 番目の例ではDRYがはるかに少なく、同じ操作を複数回実行しています。もちろん、効率は悪くなります。