在没有冗余的情况下过滤数据时使用 eloquent
Using eloquent when filtering data without redundancy
我正在尝试通过 Eloquent 过滤数据,其方法仅响应 AJAX 请求,然后 returns 视图连同过滤后的数据。但是我有一个问题:
首先,让我们看一下我的代码:
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
考虑到您在原始代码中生成的内容对我来说看起来完全有效,我不确定是否一定有最佳方法,但肯定有选择。例如,如果您有经常使用的 WHERE 子句,则可以使用作用域来集中构建旨在实现特定结果的条件,并在必要时堆叠它们。这使您将来可以灵活地更改代码中的一个位置,并在必须修改您的条件的情况下影响使用更新范围的所有其他位置。但这可能与更大的代码可维护性问题有关,而不是我认为您在此特定实例中可能正在寻找的问题。
就我个人而言,我已经多次使用了您的假设方法。当我有一个可过滤的资源的 API 端点并且过滤器可以是可变的时,它对我来说非常有用。例如,按名字、姓氏、and/or 电子邮件的任意组合搜索用户。
这对我来说是这样的:
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
}
出于几个原因,我认为这是一个很好的约定。首先,我发现代码具有很高的可读性,因为每个块都倾向于很好地自我记录(if request 有 电子邮件 ...)。其次,我可以轻松地删除任何需要在未来快速轻松地删除的块,而无需展开任何内容。
此方法的一个重要警告是每个过滤器都独立于其他过滤器 - 选择 0 个或多个过滤器的任意组合。如果您发现自己处于可以按组组合进行过滤的情况,事情就会变得有点棘手。即使在那里,您通常也可以将组合分成各自的块并实现大致相同的结果。
再一次,我认为你从问题的第一部分得到的是完全有效的,但建议将问题第二部分的代码作为更清晰、更易于维护的选项。
在我看来,您的代码可以像这样简化:
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());
}
}
我在公司的一些项目中使用了这个方法,一切正常。试一试。
我正在尝试通过 Eloquent 过滤数据,其方法仅响应 AJAX 请求,然后 returns 视图连同过滤后的数据。但是我有一个问题:
首先,让我们看一下我的代码:
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
考虑到您在原始代码中生成的内容对我来说看起来完全有效,我不确定是否一定有最佳方法,但肯定有选择。例如,如果您有经常使用的 WHERE 子句,则可以使用作用域来集中构建旨在实现特定结果的条件,并在必要时堆叠它们。这使您将来可以灵活地更改代码中的一个位置,并在必须修改您的条件的情况下影响使用更新范围的所有其他位置。但这可能与更大的代码可维护性问题有关,而不是我认为您在此特定实例中可能正在寻找的问题。
就我个人而言,我已经多次使用了您的假设方法。当我有一个可过滤的资源的 API 端点并且过滤器可以是可变的时,它对我来说非常有用。例如,按名字、姓氏、and/or 电子邮件的任意组合搜索用户。
这对我来说是这样的:
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
}
出于几个原因,我认为这是一个很好的约定。首先,我发现代码具有很高的可读性,因为每个块都倾向于很好地自我记录(if request 有 电子邮件 ...)。其次,我可以轻松地删除任何需要在未来快速轻松地删除的块,而无需展开任何内容。
此方法的一个重要警告是每个过滤器都独立于其他过滤器 - 选择 0 个或多个过滤器的任意组合。如果您发现自己处于可以按组组合进行过滤的情况,事情就会变得有点棘手。即使在那里,您通常也可以将组合分成各自的块并实现大致相同的结果。
再一次,我认为你从问题的第一部分得到的是完全有效的,但建议将问题第二部分的代码作为更清晰、更易于维护的选项。
在我看来,您的代码可以像这样简化:
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());
}
}
我在公司的一些项目中使用了这个方法,一切正常。试一试。