在没有冗余的情况下过滤数据时使用eloquent

时间:2016-03-18 21:19:21

标签: ajax laravel filter eloquent redundancy

我正在尝试通过Eloquent过滤数据,该方法只响应AJAX请求,然后返回视图以及过滤后的数据。不过我有一个问题:

首先,让我们来看看我的代码:

public function AJAX_get_reports(Request $request)
{
    if($request->ajax())
    {
        $message = $request->get('message');
        $severity = $request->get('severity');

        if(strlen($message) > 0 && strlen($severity) > 0 )
        {
            $data = ServerReport::where('severity', '=', $severity)->where('message', '=', $message)->get();
        } elseif (strlen($message) > 0) {
            $data = ServerReport::where('message', '=', $message)->get();
        } elseif (strlen($severity) > 0) {
            $data = ServerReport::where('severity', '=', $severity)->get();
        } else {
            $data = ServerReport::all();
        }
        return Response::json(View::make('dashboard.reports.index', compact('data'))->render());

    }
}

这是我能够做到的唯一方法,它有效,但我觉得这不是最好的方法,特别是如果你有更多的字段需要过滤,代码将需要大量的验证,是有最好的方法吗?

例如,在进行验证时构建查询,然后在结束时运行它?

if(strlen($message) > 0)
{
    // add WHERE to query
}
if(strlen($severity) > 0)
{
    // add WHERE to query
}

// Execute query and get the results

2 个答案:

答案 0 :(得分:1)

在我看来,您的代码可以简化为:

public function AJAX_get_reports(Request $request) {
    if($request->ajax()) {
        $message = $request->get('message');
        $severity = $request->get('severity');
        $report = ServerReport::select('*'); //Initiate the variable for query container, change * to the columns that needs to be returned or just leave it

        if (strlen($message) > 0) {
            $report->where('message', '=', $message); //Add message filter
        }

        if (strlen($severity) > 0) {
            $report->where('severity', '=', $severity); //Add severity filter
        }

        //Add another filters if needed

        $data = $report->get(); //Get the data from either the filtered data or every single data without any filters

        return Response::json(View::make('dashboard.reports.index', compact('data'))->render());
    }
}

我已经将这种方法用于我公司的一些项目,一切正常。试一试。

答案 1 :(得分:0)

我不确定是否有最好的方法来执行此操作,考虑到您在原始代码中生成的内容对我来说看起来非常有效,但肯定有选项。例如,如果您有定期使用的WHERE子句,则可以使用范围来集中构建条件以实现特定结果,并根据需要进行堆叠。这使您可以灵活地在代码中更改一个位置,并在必须修改条件的情况下影响使用更新范围的所有其他位置。但是,这可能与代码可维护性的大问题有关,而不是我认为你可能在这个特定的实例中寻找。

就个人而言,我已经使用了你的假设方法。当我有一个可过滤资源的API端点,并且过滤器可以变量时,它对我很有用。例如,通过名字,姓氏和/或电子邮件的任意组合搜索用户。

这就是我的样子:

public function getIndex(Request $request, Response $response)
{
    //Start with a copy of the model
    //I prefer to instantiate the class from the container,
    //instead of having it auto-injected using the method signature
    //just personal preference
    $users = app('App\User');

    //Filter by first name
    if ($request->has('first_name')) {
        $users->where('first_name', $request->input('first_name'));
    }

    //Filter by last name
    if ($request->has('last_name')) {
        $users->where('last_name', $request->input('last_name'));
    }

    //Filter by email
    if ($request->has('email')) {
        $users->where('email', $request->input('email'));
    }

    //If no conditions were set, get() *should* function like all()
    $data = $users->get();

    //Do what you need with the data from here on out
    //Typically I paginate the results for something like this
}

我发现这是一个很好的约定,原因有几个。首先,我发现代码具有高度可读性,因为每个块都倾向于自我自我记录(如果 电子邮件 ...)。其次,我可以轻松地删除任何需要快速轻松删除的块,而无需放松任何东西。

这种方法的一个重要注意事项是每个过滤器独立于其他过滤器 - 以任意组合选择0个或更多个过滤器。如果您发现自己处于可以按组组合过滤的情况下,会变得有点棘手。即便如此,你通常可以将组合分成他们自己的块并实现大致相同的事情。

所以再一次,我认为你在问题的第一部分所拥有的内容是完全有效的,但是会建议将问题的第二部分中的代码作为更清晰,更易于维护的选项。