2017-01-09 29 views
1

usersテーブルに250人のユーザーがいて、各ユーザーに1つ以上の書籍があり、各書籍に1つまたは複数の章があるとします。今では、ユーザー名と書籍名を印刷したいと思います。Laravel Eloquent:クエリ数を減らす

コントローラー:ブレードで

$users = User::all(); 

@foreach($users as $user) 
    <tr> 
     <td>{{ $user->id }}</td> 
     <td>{{ $user->name }}</td> 
     <td> 
     @foreach($user->books as $book) 
      {{ $book->name }}, 
      @endforeach 
     </td> 
    </tr> 
@endforeach 

# of queries 252 

N + 1問題を克服するために、クエリが今すぐクエリの#だけです

$users = User::with('books')->get(); 

する必要があります2.

I this-> BookName(章の数)のような章数で本の名前を印刷したい。だから私の刃の中で

このように、1500章の750冊については、章数が増えると照会数は約752と増えます。

これを減らすための優れた方法はありますか?生のSQLクエリを使用する必要がありますか?

+0

'with'はネストされた関係をサポートします。あなたは 'with( 'books.chapters')' – maiorano84

+0

wow ..を使うことができるはずです。ありがとう..それは動作します..あなたは読むためにどんなドキュメンテーションも提供できますか? –

+0

これを回答として追加できます。私はそれを受け入れる –

答えて

4

From the Eloquent Documentation

熱心な負荷入れ子に関係するために熱心に読み込んで

を入れ子になった、あなたは "ドット" 構文を使用することができます。あなたのケースでは

$books = App\Book::with('author.contacts')->get();

は、あなたが以下に必要な入れ子の関係を取得することができます。たとえば、1つの雄弁声明の中で、著者の個人的な連絡先の本の著者のすべてと、すべての者の熱心な負荷をしてみましょう:

User::with('books.chapters')->get(); 
3

すべてのチャプターデータをロードして、手動で各コレクションをカウントする必要はありません。代わりにwithCount()を使用してください:

$users = User::with('books')->withCount('chapters')->get(); 

あなたが実際にあなたがあなたの結果のモデルの{関連} _count列を配置しますwithCount方法を、使用することができ、それらをロードすることなく関係からの結果の数をカウントします。

+2

これは、各章オブジェクトがメモリにロードされていないので、より効率的な答えになる可能性があります。 Upvoted。 – maiorano84

+1

はい。アレクセイメゼニンにも感謝します。私は2つの新しいことを学びました。投票した –

+0

私はその点を理解しましたが、ユーザーと章の直接の関係はありません。モデルの関係は - >ユーザーが持っている多くの本、本はユーザーに属し、本には多くの虫がいる。章は本に属します。したがって、 'User :: with( 'books') - > withCount( 'chapters') - > get();'という行は、不正なメソッド呼び出しの例外を返します。未定義メソッドの呼び出し\ Database \ Query \ Builder :: chapters() ';関係を定義する方法についての任意のアイデア? –