在模型和控制器之间拆分Eloquent方法?

时间:2016-11-03 14:48:05

标签: laravel eloquent

我在控制器中有这个代码:

public function getStock(Request $request){

    $laptops = new Laptop;
    $laptops->addJoins();
    $laptops->filterResults($request);
    return $laptops->get();
}

在笔记本电脑模型中我有:

public function addJoins() {
    $this->Join('locations', 'locations.id', '=', 'laptops.location_id');
    $this->Join('models', 'models.id', '=', 'laptops.model_id');
    $this->Join('types', 'types.id', '=', 'models.type');
    $this->leftJoin('statuses', 'status.id', '=', 'laptops.status');
    $this->leftJoin('earmarks', 'earmarks.laptop', '=', 'laptop.id');
}

public function filterResults($request) {
    if ($request->stock) {
        $this->where('locations.stock', 0);
    }

    if ($request->loc) {
        $this->where('laptops.location_id', $request->loc);
    }
}

问题是我收到了所有笔记本电脑的记录,并且从URL参数过滤似乎根本不起作用。我是不是用这种结构吠叫了错误的树(我对Laravel来说很新)?

3 个答案:

答案 0 :(得分:1)

我建议你改变结构,而不是重新发明轮子。瘦的控制器,胖模型。好的做法是让控制器保持尽可能薄,所以我的控制器看起来像这样:

public function getStock(Request $request)
{
    return view('laptop.index', [
       'laptops' => Laptop::getAllLaptops($request->all())
    ]);
}

此外,使用Eloquent和scopes进行过滤等。所有与数据相关的逻辑都在模型中:

public function getAllLaptops($data)
{
    return $this->with('locations', 'models', 'types', 'statuses', 'earmarks')->search($data)->get();
}

答案 1 :(得分:1)

过滤无效,因为在$this上运行查询会导致不必要的行为,这就是本地作用域的用途。请在此处查看相关文档:

https://laravel.com/docs/master/eloquent#local-scopes

在你的情况下,它将是:

您的笔记本电脑型号:

public function scopeAddJoins($query)
{
    return $query->join('locations', 'locations.id', '=', 'laptops.location_id')
        ->join('models', 'models.id', '=', 'laptops.model_id')
        ->join('types', 'types.id', '=', 'models.type')
        ->leftJoin('statuses', 'status.id', '=', 'laptops.status')
        ->leftJoin('earmarks', 'earmarks.laptop', '=', 'laptop.id');
}

public function scopeFilterResults($query, $request)
{
    if ($request->has('stock')) {
        $query->where('locations.stock', 0);
    }

    if ($request->has('loc')) {
        $query->where('laptops.location_id', $request->input('loc'));
    }

    return $query;
}

然后你可以在你的控制器中执行此操作:

public function getStock(Request $request)
{
    return Laptop::addJoins()->filterResults($request)->get();
}

答案 2 :(得分:0)

我首先想到的是$request->stock$request->loc在您的网址参数中没有任何价值。如果你这样叫这条路线:

http://www.yoursite.com/yourpath?stock&loc

相反,尝试以这种方式使用它:

http://www.yoursite.com/yourpath?stock=1&loc=1

重点是给他们一些价值。