2013-06-24 10 views
0

"예제"테이블, "태그"테이블 및 중간 "examples_has_tags"테이블이 있습니다. 따라서 하나의 예제는 일부 태그를 가질 수 있으며 하나의 태그는 일부 예제에 속할 수 있습니다.Laravel 4 필터 관계

index.php에서 모든 예제와 태그 목록을 보여줍니다.

$examples = Example::with('tags')->where('public', true)->get(); 

$tags = Tag::all(); 

return View::make('index')->with('examples', $examples) 
          ->with('tags',  $tags); 

완벽하게 작동합니다. 그러나 어떻게 태그 이름으로 예제를 필터링 할 수 있습니까? stackoverflow에서 뭔가를 발견 : 당신이 필요로 반환하는 예제 클래스에서 정적 메서드를 만들어야합니다. 그러나 나는 데이터를 표시하는 데 지저분 해. 위의 코드에서 다음과 같이 표시합니다.

@foreach ($examples as $example) 
     <div class="widgetbox"> 
      <h4 class="widgettitle">{{ $example->name }}</h4> 
      <div class="widgetcontent"> 
       {{ $example->body }} 
       <div class="tags-list"> 
        @foreach ($example->tags as $tag) 
         <span class="label label-info tag">{{ $tag->name }}</span> 
        @endforeach 
       </div> 
      </div> 
     </div> 
    @endforeach 

간단한 방법이 있나요? , PHP 필터링없이이 일을 시도

$examples = $examples->filter(function($example) { 
     $tags = $example->tags->toArray(); 
     foreach ($tags as $tag) { 
      if ($tag["name"] == Input::get('tag')) return true; 
     } 
     return false; 
    }); 

갱신 2

: 나는 필터링 컬렉션에 대해 뭔가를 발견하지만 난 다음 해결책을 찾을 수 없습니다 예

갱신

가 없다 하지만 예제에 속한 태그를 얻을 수 없습니다.

이제 (예)

class Example extends Eloquent { 
    public function tags() 
    { 
     return $this->hasMany('Tag'); 
    } 
} 

: 0

$tagId = Tag::where('name', '=', Input::get('tag'))->first()->id; 

     $examples = Example::with('tags') 
          ->join('examples_has_tags', 'examples_has_tags.example_id', '=', 'examples.id') 
          ->where('examples_has_tags.tag_id', '=', $tagId)->get(); 

$ 예 태그 목록이 포함되어 있지 않습니다 (Eager Loading)

모델을 다음과 같이 그것을 할 수

+0

내 대안 (in_array) 접근 방법은 무엇입니까? 확인해주세요. –

+0

$ example-> tags-> toArray()는 array ("tagName1", "tagName2"...)가 아니라 array_pluck을 시도했지만 성공하지 못했습니다. 나를 위해 일하지 마라.) – Victor

+0

솔루션은 작동합니까? –

답변

0

(실제로 비어) 검색어 :

$examples = Example::with(array('tags' => function($query) 
{ 
    $query->where('name', '=', 'someName'); 
}))->get(); 

업데이트 :

$examples = $examples->filter(function($example) { 
    $tags = $example->tags->toArray(); 
    return in_array(Input::get('tag'), $tags) ?: FALSE; 
}); 
+0

제가 알기로 모든 예제를 얻을 것이고 각 예제에서 나는 태그를 필터링 할 것입니다.그러나 이것은 내가 얻으려고하는 것이 아닙니다 - 예제 목록 자체를 필터링하고 싶습니다. 나는 이미 당신의 솔루션을 시도했다고 생각하지만, 몇 시간 후에 감사 할 것입니다. – Victor

+0

아마도 어쨌든, 오해 할 수 있습니다 .-) –

+0

내 솔루션 (내 업데이트)을보십시오. 그것이 작동하는 것 같아 – Victor

0

당신이해야 할 것은 당신이 원하는 물건에 where 절을 생성 한 후 조인을 작성하고있다. 당신이 태그에 의해 필터링 할 방법에 따라, 당신은 같은 것을 할 수 있습니다

$tagIDs = array_pluck(Tag::whereIn('name', array(
    'tag1', 
    'tag2', 
    'tag3', 
))->toArray(), 'id'); 

그런 다음 tag_id하여 예를 필터링 :이

return Example::select('examples.*') 
    ->join('examples_has_tags', 'examples.id', '=', DB::raw('examples_has_tags.example_id')) 
    ->whereIn(DB::raw('examples_has_tags.tag_id'), $tagIDs) 
    ->get(); 

먼저 유효한 태그 ID를 가져 이 일을하는 더 효율적인 방법이 될 수도 있지만 아마도 이것은 내가 접근하는 방법입니다.

+0

내 솔루션 (내 게시물을 업데이트 한 경우)은 어떻습니까? 작동하는 것처럼 보입니다. – Victor

+1

예,이 해결책은 효과가 있습니다. 그러나 차이점이 있습니다. PHP를 사용하여 필터링을 수행하고 있습니다. 이를 수행하기 위해 최적화되어 있지 않기 때문에 DB 엔진보다 느립니다. 또한 모든 예제를 스크립트로 가져온 다음 나중에 필터링을 시작합니다. 1.000.000 개의 레코드가있는 데이터베이스가 있다고 상상해보십시오. DB 엔진이 필터링을 수행하게하면 (실제로)이 문제가 발생하지 않습니다. – DerLola

+0

당신이 옳다고 생각합니다.하지만 각 예제에 대한 태그 목록을 얻으려면 어떻게해야합니까? 내 게시물에서 update2보세요. 하나의 태그 만 필터링하므로 쿼리가 약간 변경되었으며 DB :: raw는 사용하지 않고 그대로 사용합니다. 나는 올바른 예제를 얻었지만 루프를 통과 할 때마다 @foreach ($ example-> tags $ 태그) 태그 배열이 비어있는 것처럼 각 예제에 대한 태그 목록을 표시하려고합니다 ... – Victor