Laravel 查询生成器。如何使查询更短?
Laravel query builder. How to make the query shorter?
我需要为数据表准备数据,我需要计算查询的过滤数据总量,但由于限制我不能只用一个查询来完成所以我几乎必须做相同的查询,但没有分页限制选项,它使我的代码量 x2。有没有可能让这段代码更短更漂亮?
public function data($request)
{
$staff = auth()->user();
$role = Role::find($staff->role_id)->alias;
$isAdmin = $role == 'admin';
$columns = ['id', 'name', 'shop', 'hash', 'status'];
$limit = $request->input('length');
$start = $request->input('start');
$order = $columns[$request->input('order.0.column')];
$directions = $request->input('order.0.dir');
$searchValue = $request->input('search.value');
$filters = explode(',', $request->input('columns.7.search')['value']);
foreach ($filters as $key => $value) {
if ($value !== "") {
array_push($shops, $value);
}
}
if ($searchValue) $filters[] = $searchValue;
$nfcs = NfcMark::offset($start)->select('nfc_marks.*')
->leftJoin('shops as s', 's.id', 'nfc_marks.shop_id')
->when(!$isAdmin, function ($q) {
$shop_ids = $this->shopRepository->shopsIdsByOwner(auth()->user()->id);
return $q->whereIn('shop_id', $shop_ids);
})
->when($searchValue, function ($q) use ($filters) {
foreach ($filters as $filter) {
$q->orWhere('shops.name', 'LIKE', '%' . $filter . '%');
}
})
->limit($limit)
->orderBy($order, $directions)
->get();
$nfcs_count = NfcMark::query()
->leftJoin('shops as s', 's.id', 'nfc_marks.shop_id')
->when(!$isAdmin, function ($q) {
$shop_ids = $this->shopRepository->shopsIdsByOwner(auth()->user()->id);
return $q->whereIn('shop_id', $shop_ids);
})
->when($searchValue, function ($q) use ($filters) {
foreach ($filters as $filter) {
$q->orWhere('shops.name', 'LIKE', '%' . $filter . '%');
}
})->get();
$totalFiltered = count($nfcs_count);
$totalData = $totalFiltered;
$data = array();
if (!empty($nfcs)) {
foreach ($nfcs as $item) {
$nestedData['id'] = $item->id;
$nestedData['name'] = $item->name;
$nestedData['shop'] = $item->shop_id;
$nestedData['hash'] = $item->hash;
$nestedData['status'] = $item->status;
$data[] = $nestedData;
}
}
$json_data = array(
"draw" => intval($request->input('draw')),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalFiltered),
"data" => $data
);
return json_encode($json_data);
}
如果您觉得需要这两个查询,您可以保留与构建器相同的查询部分,运行 这两个查询:
$query = NfcMark::leftJoin('shops as s', 's.id', 'nfc_marks.shop_id')
->when(!$isAdmin, function ($q) {
$q->whereIn(
'shop_id',
$this->shopRepository->shopsIdsByOwner(auth()->user()->id)
);
})
->when($searchValue, function ($q) use ($filters) {
foreach ($filters as $filter) {
$q->orWhere('shops.name', 'LIKE', '%' . $filter . '%');
}
});
$nfcs_count = $query->get();
$nfcs = $query->select('nfc_marks.*')
->offset($start)
->limit($limit)
->orderBy($order, $directions)
->get();
您也可以在不返回行的情况下获取计数,只需使用 count()
而不是 get()
您可以使用克隆来复制查询,然后 运行 使用不同的 where 语句。
$query1 = NfcMark::query()
->leftJoin('shops as s', 's.id', 'nfc_marks.shop_id')
->when(!$isAdmin, function ($q) {
$shop_ids = $this->shopRepository->shopsIdsByOwner(auth()->user()->id);
return $q->whereIn('shop_id', $shop_ids);
})
->when($searchValue, function ($q) use ($filters) {
foreach ($filters as $filter) {
$q->orWhere('shops.name', 'LIKE', '%' . $filter . '%');
}
})
$query2 = clone $query1;
$nfcs_count = $query1->get() //or $query1->count();
$$nfcs = $query2
->limit($limit)
->orderBy($order, $directions)
->get();
我需要为数据表准备数据,我需要计算查询的过滤数据总量,但由于限制我不能只用一个查询来完成所以我几乎必须做相同的查询,但没有分页限制选项,它使我的代码量 x2。有没有可能让这段代码更短更漂亮?
public function data($request)
{
$staff = auth()->user();
$role = Role::find($staff->role_id)->alias;
$isAdmin = $role == 'admin';
$columns = ['id', 'name', 'shop', 'hash', 'status'];
$limit = $request->input('length');
$start = $request->input('start');
$order = $columns[$request->input('order.0.column')];
$directions = $request->input('order.0.dir');
$searchValue = $request->input('search.value');
$filters = explode(',', $request->input('columns.7.search')['value']);
foreach ($filters as $key => $value) {
if ($value !== "") {
array_push($shops, $value);
}
}
if ($searchValue) $filters[] = $searchValue;
$nfcs = NfcMark::offset($start)->select('nfc_marks.*')
->leftJoin('shops as s', 's.id', 'nfc_marks.shop_id')
->when(!$isAdmin, function ($q) {
$shop_ids = $this->shopRepository->shopsIdsByOwner(auth()->user()->id);
return $q->whereIn('shop_id', $shop_ids);
})
->when($searchValue, function ($q) use ($filters) {
foreach ($filters as $filter) {
$q->orWhere('shops.name', 'LIKE', '%' . $filter . '%');
}
})
->limit($limit)
->orderBy($order, $directions)
->get();
$nfcs_count = NfcMark::query()
->leftJoin('shops as s', 's.id', 'nfc_marks.shop_id')
->when(!$isAdmin, function ($q) {
$shop_ids = $this->shopRepository->shopsIdsByOwner(auth()->user()->id);
return $q->whereIn('shop_id', $shop_ids);
})
->when($searchValue, function ($q) use ($filters) {
foreach ($filters as $filter) {
$q->orWhere('shops.name', 'LIKE', '%' . $filter . '%');
}
})->get();
$totalFiltered = count($nfcs_count);
$totalData = $totalFiltered;
$data = array();
if (!empty($nfcs)) {
foreach ($nfcs as $item) {
$nestedData['id'] = $item->id;
$nestedData['name'] = $item->name;
$nestedData['shop'] = $item->shop_id;
$nestedData['hash'] = $item->hash;
$nestedData['status'] = $item->status;
$data[] = $nestedData;
}
}
$json_data = array(
"draw" => intval($request->input('draw')),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalFiltered),
"data" => $data
);
return json_encode($json_data);
}
如果您觉得需要这两个查询,您可以保留与构建器相同的查询部分,运行 这两个查询:
$query = NfcMark::leftJoin('shops as s', 's.id', 'nfc_marks.shop_id')
->when(!$isAdmin, function ($q) {
$q->whereIn(
'shop_id',
$this->shopRepository->shopsIdsByOwner(auth()->user()->id)
);
})
->when($searchValue, function ($q) use ($filters) {
foreach ($filters as $filter) {
$q->orWhere('shops.name', 'LIKE', '%' . $filter . '%');
}
});
$nfcs_count = $query->get();
$nfcs = $query->select('nfc_marks.*')
->offset($start)
->limit($limit)
->orderBy($order, $directions)
->get();
您也可以在不返回行的情况下获取计数,只需使用 count()
而不是 get()
您可以使用克隆来复制查询,然后 运行 使用不同的 where 语句。
$query1 = NfcMark::query()
->leftJoin('shops as s', 's.id', 'nfc_marks.shop_id')
->when(!$isAdmin, function ($q) {
$shop_ids = $this->shopRepository->shopsIdsByOwner(auth()->user()->id);
return $q->whereIn('shop_id', $shop_ids);
})
->when($searchValue, function ($q) use ($filters) {
foreach ($filters as $filter) {
$q->orWhere('shops.name', 'LIKE', '%' . $filter . '%');
}
})
$query2 = clone $query1;
$nfcs_count = $query1->get() //or $query1->count();
$$nfcs = $query2
->limit($limit)
->orderBy($order, $directions)
->get();