如何按父对象的关系过滤 laravel 中的数据
How to filter data in laravel by relationship of parent object
我有 3 个模型:Client
、Organization
和 Industry
。我想过滤和显示分配给所选行业中任何组织的客户。
关系:
Client N-N Organization N-N Industry
一个客户可以有多个组织,一个组织可以有多个行业。我使用带有 GET
方法的表单。
我的控制器:
class ClientListsController extends Controller
{
public function index()
{
$clients = new Client;
$queries = array();
$columns = ['statuses'];
foreach ($columns as $column) {
if (request()->has($column)) {
if ($column == 'industries') {
// filter by industries
}
if ($column == 'statuses' && request($column) == 1 ) {
$clients = optional($clients->has('organizations'))->paginate(100, ['*'], 'client_page');
}else if($column == 'statuses' && request($column) == null ){
$clients = Client::paginate(100, ['*'], 'client_page');
}
else{
$clients = $clients->whereDoesntHave('organizations')->paginate(100, ['*'], 'client_page');
}
$queries[$column] = request($column);
}else{
$clients = Client::paginate(100, ['*'], 'client_page');
}
}
$organizations = Organization::paginate(100, ['*'], 'org_page');
return view('clientLists.index')->with(['clients' => $clients, 'organizations' => $organizations]);
}
}
我已经尝试了多种方法,例如循环遍历组织的当前结果,但在使用 has() 时返回 true 或 false。
我也尝试过使用 $clients = Client::all()
但我的意思是进一步分页所以我使用 Client::where('id', '*')
所以我没有得到集合,但那导致 statuses
过滤器确实不行。
我正在与 Laravel 6 合作。你知道如何使用分页进行通用过滤吗?非常感谢!
编辑
详细相关关系(f.e。客户的枢轴 table - 组织是 client_organization
),并定义了外键。
App\Client
public function Organizations()
{
return $this->belongsToMany('App\Organization')->withTimestamps();
}
App\Organization
public function Clients()
{
return $this->belongsToMany('App\Client')->withTimestamps();
}
public function Industries()
{
return $this->belongsToMany('App\Industry')->withTimestamps();
}
App\Industry
public function Organizations()
{
return $this->belongsToMany('App\Organization')->withTimestamps();
}
编辑 2:
我试图通过 SQL 查询来实现我的目标,但我被 JOINS
与多对多关系所困。
$clients = DB::table('clients')
->leftJoin('client_organization', 'client_organization.client_id', '=', 'clients.id')->leftJoin('industry_organization', 'industry_organization.organization_id', '=', 'organizations.id')
->whereIn('industry_organization.industry_id', request($column))
->paginate(100, ['*'], 'client_page');
}
select
count(*) as aggregate
from
`clients`
left join `client_organization` on `client_organization`.`client_id` = `clients`.`id`
left join `industry_organization` on `industry_organization`.`organization_id` = `organizations`.`id`
where
`industry_organization`.`industry_id` in (2)`
本次查询returnsColumn not found: 1054 Unknown column 'organizations.id' in 'on clause'
因此,如果您有 $industry
,您可以使用您的关系找到其中的所有组织:
$organisations = $industry->organisations();
然后,您想要获取每个组织的所有客户:
$clients = [];
foreach ($organisations as $organisation) {
$clients[$organisation] = $orgination->clients()->toArray();
}
或者,也可以在一个查询中试一试:
$industries = request($column);
$clients = DB::table('clients')
->leftJoin('client_organization', 'client_organization.client_id', '=', 'clients.id')
->leftJoin('organizations', 'organizations.id', '=', 'client_organization.id')
->leftJoin('industry_organization', 'industry_organization.organization_id', '=', 'organizations.id')
->whereIn('organisations.industry_id', $industries)
->paginate(10);
逐行尝试检查并轻松调试(在第一个 leftJoin
之后尝试 ->get()
并检查它是否有效;如果可以,在第二个之后尝试。
我是这样做的:
if (request()->industries[0] != "") {
$clients = $clients->with('organizations')->whereHas('organizations', function($query){
$query->with('industries')->whereHas('industries', function($query2){
$query2->whereIn('industry_id', request()->industries);
});
});
}
感谢小伙伴们的帮助:)
我有 3 个模型:Client
、Organization
和 Industry
。我想过滤和显示分配给所选行业中任何组织的客户。
关系:
Client N-N Organization N-N Industry
一个客户可以有多个组织,一个组织可以有多个行业。我使用带有 GET
方法的表单。
我的控制器:
class ClientListsController extends Controller
{
public function index()
{
$clients = new Client;
$queries = array();
$columns = ['statuses'];
foreach ($columns as $column) {
if (request()->has($column)) {
if ($column == 'industries') {
// filter by industries
}
if ($column == 'statuses' && request($column) == 1 ) {
$clients = optional($clients->has('organizations'))->paginate(100, ['*'], 'client_page');
}else if($column == 'statuses' && request($column) == null ){
$clients = Client::paginate(100, ['*'], 'client_page');
}
else{
$clients = $clients->whereDoesntHave('organizations')->paginate(100, ['*'], 'client_page');
}
$queries[$column] = request($column);
}else{
$clients = Client::paginate(100, ['*'], 'client_page');
}
}
$organizations = Organization::paginate(100, ['*'], 'org_page');
return view('clientLists.index')->with(['clients' => $clients, 'organizations' => $organizations]);
}
}
我已经尝试了多种方法,例如循环遍历组织的当前结果,但在使用 has() 时返回 true 或 false。
我也尝试过使用 $clients = Client::all()
但我的意思是进一步分页所以我使用 Client::where('id', '*')
所以我没有得到集合,但那导致 statuses
过滤器确实不行。
我正在与 Laravel 6 合作。你知道如何使用分页进行通用过滤吗?非常感谢!
编辑
详细相关关系(f.e。客户的枢轴 table - 组织是 client_organization
),并定义了外键。
App\Client
public function Organizations()
{
return $this->belongsToMany('App\Organization')->withTimestamps();
}
App\Organization
public function Clients()
{
return $this->belongsToMany('App\Client')->withTimestamps();
}
public function Industries()
{
return $this->belongsToMany('App\Industry')->withTimestamps();
}
App\Industry
public function Organizations()
{
return $this->belongsToMany('App\Organization')->withTimestamps();
}
编辑 2:
我试图通过 SQL 查询来实现我的目标,但我被 JOINS
与多对多关系所困。
$clients = DB::table('clients')
->leftJoin('client_organization', 'client_organization.client_id', '=', 'clients.id')->leftJoin('industry_organization', 'industry_organization.organization_id', '=', 'organizations.id')
->whereIn('industry_organization.industry_id', request($column))
->paginate(100, ['*'], 'client_page');
}
select
count(*) as aggregate
from
`clients`
left join `client_organization` on `client_organization`.`client_id` = `clients`.`id`
left join `industry_organization` on `industry_organization`.`organization_id` = `organizations`.`id`
where
`industry_organization`.`industry_id` in (2)`
本次查询returnsColumn not found: 1054 Unknown column 'organizations.id' in 'on clause'
因此,如果您有 $industry
,您可以使用您的关系找到其中的所有组织:
$organisations = $industry->organisations();
然后,您想要获取每个组织的所有客户:
$clients = [];
foreach ($organisations as $organisation) {
$clients[$organisation] = $orgination->clients()->toArray();
}
或者,也可以在一个查询中试一试:
$industries = request($column);
$clients = DB::table('clients')
->leftJoin('client_organization', 'client_organization.client_id', '=', 'clients.id')
->leftJoin('organizations', 'organizations.id', '=', 'client_organization.id')
->leftJoin('industry_organization', 'industry_organization.organization_id', '=', 'organizations.id')
->whereIn('organisations.industry_id', $industries)
->paginate(10);
逐行尝试检查并轻松调试(在第一个 leftJoin
之后尝试 ->get()
并检查它是否有效;如果可以,在第二个之后尝试。
我是这样做的:
if (request()->industries[0] != "") {
$clients = $clients->with('organizations')->whereHas('organizations', function($query){
$query->with('industries')->whereHas('industries', function($query2){
$query2->whereIn('industry_id', request()->industries);
});
});
}
感谢小伙伴们的帮助:)