2014-09-23 4 views
0

카테고리 목록을 보여 주며 각 카테고리 내의 기사 수를 표시합니다. 예상 된 결과를 얻었지만 N + 1 문제가 발생했습니다.N + 1 문제없이 전체적인 모델을 로딩하는 방법

CategoriesController 인덱스 기능 :

public function index() 
{ 
    return View::make('categories.index', [ 
     'articleCategories' => Category::where('type', 'articles')->orderBy('name')->get(), 
    ]); 
} 

Category 모델이 기사에 대한 많은 관계 :

public function articles() 
{ 
    return $this->hasMany('Article'); 
} 

categories.index보기 :

@foreach($articleCategories as $articleCategory) 
    <p> 
    {{ HTML::link(URL::route('articles.category', array('category' => Str::slug($articleCategory->name))), $articleCategory->name) }} 
    {{ $articleCategory->articles->count() }} 
    </p> 
@endforeach 

편집 : 그것을 만약 내가 열심히 모든 관련 기사를로드 열심히하지만, 난 단지 과도한 것 같습니다 문서 개수가 범주를 필요 이후 작동합니다. 열심히 기사를로드하고 ->count() 성능에 영향을 줍니까? 아니면 이것을 수행하는 가장 좋은 방법입니까?

+0

왜하지 않는다 :'수 ($ articleCategory-> 기사),'? 나는 그것이 가장 쉽고 빠르다고 생각합니다. – ArjanSchouten

+0

답장을 보내 주셔서 감사합니다. 나는 그 방법으로 작업하게 만들었지 만 이상적으로는 관련된 모든 기사를로드하고 싶지 않습니다. 나는 내 질문을 업데이트했다. –

+1

여러 개의 Eloquent 모델을로드하는 것이 잔인합니다. 100 개의 행이 있다면 걱정할 필요가 없습니다.하지만 수천 개의 행에 대해서는 확실히 그렇게하지 않을 것입니다. –

답변

1
// helper relation 
public function articlesCount() 
{ 
    return $this->hasOne('Article')->selectRaw('category_id, count(*) as aggregate')->groupBy('category_id'); 
} 

// and accessor for fetching it easier 
public function getArticlesCountAttribute() 
{ 
    if (! array_key_exists('articlesCount', $this->relations)) $this->load('articlesCount'); 

    return $this->getRelation('articlesCount')->aggregate; 
} 

그럼 당신은이 작업을 수행 할 수 있습니다

// eager load in single query 
$categories = Category::with('articlesCount')->get(); 

// thanks to accessor this will return value and load relation only if needed 
$categories->first()->articlesCount; 
+0

다시 한번 감사드립니다. Jarek, 아직 이것을 시험해 볼 시간이 없었습니다. 내가 할 때 받아 들일거야. –

0

범주 데이터는 단지

$category->type을하거나 당신이 이름 필드가 있다면 당신이 기사를 얻으려면 $category->name

하여 이름을 얻을 수 있습니다 얻을보기 지금이

public function index() 
{ 
    return View::make('categories.index', [ 
     'category' => Category::with('articles')->where('type', 'articles')->orderBy('name')->get(), 
    ]); 
} 

시도 할 수있는 카테고리의 이름

foreach($category->articles as $article) 
// do something with the articles 
@endforeach 

g 귀하가 카테고리의 기사 수를 계산하십시오. $category->articles->count();

Eager loading의 문서를 한 번 읽었는지 확인하십시오. 실제로 많은 도움이됩니다.

+0

감사합니다.이 방법에 익숙합니다. 하지만 카운트 만 필요하기 때문에 모든 관련 기사를로드하는 것이 과도한 것으로 보인다. 이것이 성능에 영향을 미칩니 까? –

+0

나는 당신의 요지를 얻는다. 나는 성능상의 문제가 많이있을 것이라고 생각하지 않는다. 그러나 생각할 수있는 다른 방법은 왼쪽에있는 카테고리 모델에 기사를 합류 한 다음 countArticles 메소드의 기사 수를 계산하는 것이다. 전통적인 방법, 나는 믿습니다. –