首页 文章

Laravel 4过滤关系

提问于
浏览
0

我有“examples”表,“tags”表和中间“examples_has_tags”表 . 因此,一个示例可以包含一些标记,一个标记可以属于某些示例 .

在index.php中,我显示了所有示例和标记列表 .

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

$tags = Tag::all();

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

完美的工作 . 但是如何按标签名称过滤示例?我在stackoverflow上找到了一些东西:你应该在Example类中创建一个返回我需要的静态方法 . 但是我对显示数据感到麻烦 . 在上面的代码中,我显示如下:

@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

有一个简单的方法吗?我找到了一些有关过滤集合的内容,但没有例子

update

我找到了下一个解决方案:

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

update2

尝试在没有PHP过滤的情况下执行此操作,但我无法获取属于示例的标记:

$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();

$ examples不包含标签列表(实际上它是空的)

2 回答

  • 0

    你应该做的是创建一个连接,然后在你想要的东西上创建一个where子句 . 根据您希望按标记过滤的方式,您可能会执行以下操作:

    首先获取有效的标记ID:

    $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();
    

    可能有(并且可能是)更有效的方法,但这就是我接近它的方式 .

  • 0

    你可以这样做(Eager Loading

    Model : (示例)

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

    现在查询:

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

    Update :

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

相关问题