如何按数据透视表中的数据过滤集合

时间:2015-12-06 23:14:54

标签: php laravel-5.1

我有一个存储在变量'$ articles'中的对象集合。每篇文章都有1-3个类别。可以通过变量'$ catIDs'访问这些类别(见下文)。我还有一个存储在变量'$ categoryChoice'中的1-3个类别的集合。这些是用户选择的类别。

我只想显示存储在变量'$ categoryChoice'中的一个或多个类别的文章。我几乎在那里,但我不知道如何将'$ catIDs'与每篇特定文章相关联,然后将它们与'$ categoryChoice'ID匹配。

我查看了文档HEREHERE,但我迷路了! (Laravel 5)

数据库表:'文章'(id,title等等)'categories'(id,name)'article_category'(article_id,category_id)

我的文章控制器:

public function index(Request $request)
{
$lat = $request->get('lat');
$lng = $request->get('lng');
//  THIS GETS THE USER DEFINED CATEGORY CHOICES
$categoryChoice = $request->get('categoryList');
$distance = 1;

$query = Article::getByDistance($lat, $lng, $distance);
    if(empty($query)) 
    {
        return redirect()->action('HomeController@index');
    }

$ids = [];

    //Extracts the article/store id's
foreach($query as $q)
{
      array_push($ids, $q->id);
}

$articles = Article::find($ids);

$catIDs = [];

foreach ($articles as $article)
{

    array_push($catIDs, $article->categories->lists('id'));

}

// if $categoryChoice is equal to $catIDs only show those articles.


    return view('articles.index', compact('categories', 'days'))->withArticles($articles);

}

以下是我的文章模型的相关部分:

public function categories()
{
  return $this->belongsToMany('App\Category')->withTimestamps();
}
public static function getByDistance($lat, $lng, $distance)
{
 $results = DB::select(DB::raw('SELECT id, ( 3959 * acos( cos( radians(' . $lat . ') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(' . $lng . ') ) + sin( radians(' . $lat .') ) * sin( radians(lat) ) ) ) AS distance FROM articles HAVING distance < ' . $distance . ' ORDER BY distance') );
 return $results;
}

1 个答案:

答案 0 :(得分:2)

在您的文章模型中,您应该建立关系

public function categories()
{
    return $this->belongsToMany('App\Category');
}

然后你可以查询关系:

$articles = Article::whereHas('categories', function ($query) use ($categoryChoice) {    
    $query->whereIn('categories.id', $categoryChoice);    
})->get();

你在这里也有一个查询距离。 getByDistance听起来像一个查询范围。如果您更改该方法以返回查询(不要get()结果,只需返回您可以链接方法的$query对象。如果您想使用laravel命名约定,您可以调用它scopeDistance($lat, $lng, $distance)并将其引用为distance

然后您的索引方法简化为:

public function index(Request $request)
{

    $lat = $request->get('lat');
    $lng = $request->get('lng');
    $distance = 1;

    //  THIS GETS THE USER DEFINED CATEGORY CHOICES
    $categoryChoice = $request->get('categoryList');

    $query = Article::distance($lat, $lng, $distance)
        ->whereHas('categories', function ($query) use ($categoryChoice) {    
            $query->whereIn('categories.id', $categoryChoice);    
        })->get();


    if(count($articles) == 0) 
    {
        return redirect()->action('HomeController@index');
    }

    return view('articles.index', compact('categories', 'articles'));

}