Laravel 显示关联结果
Laravel display relation results
从 URL 我得到了 $filter
、$month
或两者。例如,当我只想显示 11 月的结果时,使用下面的代码一切正常。但是,当还设置了过滤器时,如果在数据库中找到过滤器,它会显示所有结果(也来自其他月份)。
我想要实现的是,如果已在数据库中找到设置的过滤器,则仅显示结果,如果已设置月份,则也仅显示该特定月份的结果。
我的 Section 和 Expense 模型分别有 belongsTo 和 hasMany 关系。
$query = Section::query();
如果设置了过滤器:
if ($filter !== 'false') {
$query->with(['expenses' => function ($query) use ($month) {
$query->where('date', 'LIKE', '%2015-' . Carbon::parse($month)->format('m') . '%');
}]);
}
如果设置了月份:
if ($month !== 'false') {
$query->with(['expenses' => function ($query) use ($filter) {
$query->where('type', '=', $filter);
}]);
}
我也试过下面的代码:
if ($filter !== 'false') {
$query->with('expenses')->whereHas('expenses', function($query) use ($filter) {
$query->where('type', '=', $filter);
});
}
if ($month !== 'false') {
$query->with('expenses')->whereHas('expenses', function($query) use ($month) {
$query->where('date', 'LIKE', '%2015-' . Carbon::parse($month)->format('m') . '%');
});
}
$expenses = $query->orderBy('section', 'asc')->paginate(25);
我在 $expenses
上使用 foreach 在我看来显示结果。
按照您的方式,您正在用另一个覆盖一个急切加载约束。您需要将所有检查移动到一个预加载约束中,如下所示:
$query->with(['expenses' => function ($q) use ($month, $filter) {
if ($month !== 'false') {
$q->where('date', 'LIKE', '%2015-' . Carbon::parse($month)->format('m') . '%');
}
if ($filter !== 'false') {
$q->where('type', '=', $filter);
}
}]);
你需要将两者结合起来,否则最后一个会扰乱第一个 eloquent 模型设置的状态。
要快速修复并了解发生了什么,请尝试:
if ($filter !== 'false') {
$query = $query->with('expenses')->whereHas('expenses', function($query) use ($filter) {
$query->where('type', '=', $filter);
});
}
if ($month !== 'false') {
$query = $query->with('expenses')->whereHas('expenses', function($query) use ($month) {
$query->where('date', 'LIKE', '%2015-' . Carbon::parse($month)->format('m') . '%');
});
}
$expenses = $query->orderBy('section', 'asc')->paginate(25);
在正确的场景中,您应该处理内部闭包内的所有 AND 条件。
可以使用
来完成
$query->where(condition1);
$query->where(condition2);
或
$query->where(condition1)
->where(condition2);
看看这个answer and this documentation
从 URL 我得到了 $filter
、$month
或两者。例如,当我只想显示 11 月的结果时,使用下面的代码一切正常。但是,当还设置了过滤器时,如果在数据库中找到过滤器,它会显示所有结果(也来自其他月份)。
我想要实现的是,如果已在数据库中找到设置的过滤器,则仅显示结果,如果已设置月份,则也仅显示该特定月份的结果。
我的 Section 和 Expense 模型分别有 belongsTo 和 hasMany 关系。
$query = Section::query();
如果设置了过滤器:
if ($filter !== 'false') {
$query->with(['expenses' => function ($query) use ($month) {
$query->where('date', 'LIKE', '%2015-' . Carbon::parse($month)->format('m') . '%');
}]);
}
如果设置了月份:
if ($month !== 'false') {
$query->with(['expenses' => function ($query) use ($filter) {
$query->where('type', '=', $filter);
}]);
}
我也试过下面的代码:
if ($filter !== 'false') {
$query->with('expenses')->whereHas('expenses', function($query) use ($filter) {
$query->where('type', '=', $filter);
});
}
if ($month !== 'false') {
$query->with('expenses')->whereHas('expenses', function($query) use ($month) {
$query->where('date', 'LIKE', '%2015-' . Carbon::parse($month)->format('m') . '%');
});
}
$expenses = $query->orderBy('section', 'asc')->paginate(25);
我在 $expenses
上使用 foreach 在我看来显示结果。
按照您的方式,您正在用另一个覆盖一个急切加载约束。您需要将所有检查移动到一个预加载约束中,如下所示:
$query->with(['expenses' => function ($q) use ($month, $filter) {
if ($month !== 'false') {
$q->where('date', 'LIKE', '%2015-' . Carbon::parse($month)->format('m') . '%');
}
if ($filter !== 'false') {
$q->where('type', '=', $filter);
}
}]);
你需要将两者结合起来,否则最后一个会扰乱第一个 eloquent 模型设置的状态。
要快速修复并了解发生了什么,请尝试:
if ($filter !== 'false') {
$query = $query->with('expenses')->whereHas('expenses', function($query) use ($filter) {
$query->where('type', '=', $filter);
});
}
if ($month !== 'false') {
$query = $query->with('expenses')->whereHas('expenses', function($query) use ($month) {
$query->where('date', 'LIKE', '%2015-' . Carbon::parse($month)->format('m') . '%');
});
}
$expenses = $query->orderBy('section', 'asc')->paginate(25);
在正确的场景中,您应该处理内部闭包内的所有 AND 条件。
可以使用
来完成$query->where(condition1);
$query->where(condition2);
或
$query->where(condition1)
->where(condition2);
看看这个answer and this documentation