Eager load many more things. Fixes a lot of n+1 queries in ajax/bootstrap tables requests (#2832)

This commit is contained in:
Daniel Meltzer 2016-10-28 16:15:13 -05:00 committed by snipe
parent 86ef44b43d
commit 3a8edfdf58
9 changed files with 108 additions and 43 deletions

View file

@ -530,9 +530,11 @@ class AccessoriesController extends Controller
**/ **/
public function getDatatable(Request $request) public function getDatatable(Request $request)
{ {
$accessories = Company::scopeCompanyables(Accessory::select('accessories.*')->with('category', 'company')) $accessories = Company::scopeCompanyables(
->whereNull('accessories.deleted_at'); Accessory::select('accessories.*')
->whereNull('accessories.deleted_at')
->with('category', 'company', 'manufacturer', 'users', 'location')
);
if (Input::has('search')) { if (Input::has('search')) {
$accessories = $accessories->TextSearch(e(Input::get('search'))); $accessories = $accessories->TextSearch(e(Input::get('search')));
} }

View file

@ -416,7 +416,7 @@ class AssetModelsController extends Controller
public function getDatatable($status = null) public function getDatatable($status = null)
{ {
$models = AssetModel::with('category', 'assets', 'depreciation'); $models = AssetModel::with('category', 'assets', 'depreciation', 'manufacturer');
switch ($status) { switch ($status) {
case 'Deleted': case 'Deleted':
@ -491,7 +491,7 @@ class AssetModelsController extends Controller
*/ */
public function getDataView($modelID) public function getDataView($modelID)
{ {
$assets = Asset::where('model_id', '=', $modelID)->with('company'); $assets = Asset::where('model_id', '=', $modelID)->with('company', 'assetstatus');
if (Input::has('search')) { if (Input::has('search')) {
$assets = $assets->TextSearch(e(Input::get('search'))); $assets = $assets->TextSearch(e(Input::get('search')));

View file

@ -307,9 +307,9 @@ class CategoriesController extends Controller
public function getDataViewAssets($categoryID) public function getDataViewAssets($categoryID)
{ {
$category = Category::with('assets.company')->find($categoryID); $category = Category::find($categoryID);
$category = $category->load('assets.company', 'assets.model', 'assets.assetstatus', 'assets.assigneduser');
$category_assets = $category->assets(); $category_assets = $category->assets();
if (Input::has('search')) { if (Input::has('search')) {
$category_assets = $category_assets->TextSearch(e(Input::get('search'))); $category_assets = $category_assets->TextSearch(e(Input::get('search')));
} }
@ -333,7 +333,6 @@ class CategoriesController extends Controller
$count = $category_assets->count(); $count = $category_assets->count();
$category_assets = $category_assets->skip($offset)->take($limit)->get(); $category_assets = $category_assets->skip($offset)->take($limit)->get();
$rows = array(); $rows = array();
foreach ($category_assets as $asset) { foreach ($category_assets as $asset) {
$actions = ''; $actions = '';
@ -364,7 +363,7 @@ class CategoriesController extends Controller
'assigned_to' => ($asset->assigneduser) ? (string)link_to('/admin/users/'.$asset->assigneduser->id.'/view', $asset->assigneduser->fullName()): '', 'assigned_to' => ($asset->assigneduser) ? (string)link_to('/admin/users/'.$asset->assigneduser->id.'/view', $asset->assigneduser->fullName()): '',
'change' => $inout, 'change' => $inout,
'actions' => $actions, 'actions' => $actions,
'companyName' => Company::getName($asset), 'companyName' => is_null($asset->company) ? '' : e($asset->company->name)
); );
} }

View file

@ -390,8 +390,11 @@ class ConsumablesController extends Controller
*/ */
public function getDatatable() public function getDatatable()
{ {
$consumables = Company::scopeCompanyables(Consumable::select('consumables.*')->whereNull('consumables.deleted_at') $consumables = Company::scopeCompanyables(
->with('company', 'location', 'category', 'users')); Consumable::select('consumables.*')
->whereNull('consumables.deleted_at')
->with('company', 'location', 'category', 'users', 'manufacturer')
);
if (Input::has('search')) { if (Input::has('search')) {
$consumables = $consumables->TextSearch(e(Input::get('search'))); $consumables = $consumables->TextSearch(e(Input::get('search')));

View file

@ -742,6 +742,7 @@ class LicensesController extends Controller
{ {
$license = License::find($licenseId); $license = License::find($licenseId);
$license = $license->load('assignedusers', 'licenseSeats.user', 'licenseSeats.asset');
if (isset($license->id)) { if (isset($license->id)) {
@ -947,7 +948,7 @@ class LicensesController extends Controller
*/ */
public function getDatatable() public function getDatatable()
{ {
$licenses = Company::scopeCompanyables(License::with('company')); $licenses = Company::scopeCompanyables(License::with('company', 'licenseSeatsRelation', 'manufacturer'));
if (Input::has('search')) { if (Input::has('search')) {
$licenses = $licenses->TextSearch(Input::get('search')); $licenses = $licenses->TextSearch(Input::get('search'));
@ -991,7 +992,7 @@ class LicensesController extends Controller
'id' => $license->id, 'id' => $license->id,
'name' => (string) link_to('/admin/licenses/'.$license->id.'/view', $license->name), 'name' => (string) link_to('/admin/licenses/'.$license->id.'/view', $license->name),
'serial' => (string) link_to('/admin/licenses/'.$license->id.'/view', mb_strimwidth($license->serial, 0, 50, "...")), 'serial' => (string) link_to('/admin/licenses/'.$license->id.'/view', mb_strimwidth($license->serial, 0, 50, "...")),
'totalSeats' => $license->totalSeatsByLicenseID(), 'totalSeats' => $license->licenseSeatsCount,
'remaining' => $license->remaincount(), 'remaining' => $license->remaincount(),
'license_name' => e($license->license_name), 'license_name' => e($license->license_name),
'license_email' => e($license->license_email), 'license_email' => e($license->license_email),

View file

@ -257,7 +257,7 @@ class ManufacturersController extends Controller
*/ */
public function getDataView($manufacturerId, $itemtype = null) public function getDataView($manufacturerId, $itemtype = null)
{ {
$manufacturer = Manufacturer::with('assets.company')->find($manufacturerId); $manufacturer = Manufacturer::find($manufacturerId);
switch ($itemtype) { switch ($itemtype) {
case "assets": case "assets":
@ -276,6 +276,7 @@ class ManufacturersController extends Controller
protected function getDataAssetsView(Manufacturer $manufacturer) protected function getDataAssetsView(Manufacturer $manufacturer)
{ {
$manufacturer = $manufacturer->load('assets.model', 'assets.assigneduser', 'assets.assetstatus', 'assets.company');
$manufacturer_assets = $manufacturer->assets; $manufacturer_assets = $manufacturer->assets;
if (Input::has('search')) { if (Input::has('search')) {
@ -329,20 +330,22 @@ class ManufacturersController extends Controller
'serial' => e($asset->serial), 'serial' => e($asset->serial),
'assigned_to' => ($asset->assigneduser) ? (string)link_to('/admin/users/'.$asset->assigneduser->id.'/view', e($asset->assigneduser->fullName())): '', 'assigned_to' => ($asset->assigneduser) ? (string)link_to('/admin/users/'.$asset->assigneduser->id.'/view', e($asset->assigneduser->fullName())): '',
'actions' => $actions, 'actions' => $actions,
'companyName' => e(Company::getName($asset)), // 'companyName' => e(Company::getName($asset)),
'companyName' => is_null($asset->company) ? '' : $asset->company->name
); );
if (isset($inout)) { if (isset($inout)) {
$row['change'] = $inout; $row['change'] = $inout;
}
} }
}
$data = array('total' => $count, 'rows' => $rows); $data = array('total' => $count, 'rows' => $rows);
return $data; return $data;
} }
protected function getDataLicensesView(Manufacturer $manufacturer) protected function getDataLicensesView(Manufacturer $manufacturer)
{ {
$manufacturer = $manufacturer->load('licenses.company', 'licenses.manufacturer', 'licenses.licenseSeatsRelation');
$licenses = $manufacturer->licenses; $licenses = $manufacturer->licenses;
if (Input::has('search')) { if (Input::has('search')) {
@ -380,7 +383,7 @@ class ManufacturersController extends Controller
'id' => $license->id, 'id' => $license->id,
'name' => (string) link_to('/admin/licenses/'.$license->id.'/view', $license->name), 'name' => (string) link_to('/admin/licenses/'.$license->id.'/view', $license->name),
'serial' => (string) link_to('/admin/licenses/'.$license->id.'/view', mb_strimwidth($license->serial, 0, 50, "...")), 'serial' => (string) link_to('/admin/licenses/'.$license->id.'/view', mb_strimwidth($license->serial, 0, 50, "...")),
'totalSeats' => $license->totalSeatsByLicenseID(), 'totalSeats' => $license->licenseSeatCount,
'remaining' => $license->remaincount(), 'remaining' => $license->remaincount(),
'license_name' => e($license->license_name), 'license_name' => e($license->license_name),
'license_email' => e($license->license_email), 'license_email' => e($license->license_email),
@ -403,6 +406,13 @@ class ManufacturersController extends Controller
public function getDataAccessoriesView(Manufacturer $manufacturer) public function getDataAccessoriesView(Manufacturer $manufacturer)
{ {
$manufacturer = $manufacturer->load(
'accessories.location',
'accessories.company',
'accessories.category',
'accessories.manufacturer',
'accessories.users'
);
$accessories = $manufacturer->accessories; $accessories = $manufacturer->accessories;
if (Input::has('search')) { if (Input::has('search')) {
@ -461,6 +471,13 @@ class ManufacturersController extends Controller
public function getDataConsumablesView($manufacturer) public function getDataConsumablesView($manufacturer)
{ {
$manufacturer = $manufacturer->load(
'consumables.location',
'consumables.company',
'consumables.category',
'consumables.manufacturer',
'consumables.users'
);
$consumables = $manufacturer->consumables; $consumables = $manufacturer->consumables;
if (Input::has('search')) { if (Input::has('search')) {

View file

@ -242,7 +242,7 @@ class SuppliersController extends Controller
public function getDatatable() public function getDatatable()
{ {
$suppliers = Supplier::select(array('id','name','address','address2','city','state','country','fax', 'phone','email','contact')) $suppliers = Supplier::with('assets', 'licenses')->select(array('id','name','address','address2','city','state','country','fax', 'phone','email','contact'))
->whereNull('deleted_at'); ->whereNull('deleted_at');
if (Input::has('search')) { if (Input::has('search')) {
@ -283,8 +283,8 @@ class SuppliersController extends Controller
'phone' => e($supplier->phone), 'phone' => e($supplier->phone),
'fax' => e($supplier->fax), 'fax' => e($supplier->fax),
'email' => ($supplier->email!='') ? '<a href="mailto:'.e($supplier->email).'">'.e($supplier->email).'</a>' : '', 'email' => ($supplier->email!='') ? '<a href="mailto:'.e($supplier->email).'">'.e($supplier->email).'</a>' : '',
'assets' => $supplier->num_assets(), 'assets' => $supplier->assets->count(),
'licenses' => $supplier->num_licenses(), 'licenses' => $supplier->licenses->count(),
'actions' => $actions 'actions' => $actions
); );
} }

View file

@ -101,6 +101,20 @@ class License extends Depreciable
->count(); ->count();
} }
// We do this to eager load the "count" of seats from the controller. Otherwise calling "count()" on each model results in n+1
public function licenseSeatsRelation()
{
return $this->hasMany(LicenseSeat::class)->whereNull('deleted_at')->selectRaw('license_id, count(*) as count')->groupBy('license_id');
}
public function getLicenseSeatsCountAttribute()
{
if ($this->licenseSeatsRelation->first()) {
return $this->licenseSeatsRelation->first()->count;
}
return 0;
}
/** /**
* Get total licenses not checked out * Get total licenses not checked out
@ -116,37 +130,47 @@ class License extends Depreciable
/** /**
* Get the number of available seats * Get the number of available seats
*/ */
public function availcount() public function availCount()
{ {
return LicenseSeat::whereNull('assigned_to') return $this->licenseSeatsRelation()
->whereNull('asset_id') ->whereNull('asset_id');
->where('license_id', '=', $this->id) }
->whereNull('deleted_at')
->count(); public function getAvailSeatsCountAttribute()
{
if ($this->availCount->first()) {
return $this->availCount->first()->count;
}
return 0;
} }
/** /**
* Get the number of assigned seats * Get the number of assigned seats
* *
*/ */
public function assignedcount() public function assignedCount()
{ {
return $this->licenseSeatsRelation()->where(function ($query) {
$query->whereNotNull('assigned_to')
->orWhereNotNull('asset_id');
});
}
return \App\Models\LicenseSeat::where('license_id', '=', $this->id) public function getAssignedSeatsCountAttribute()
->where(function ($query) { {
// dd($this->licenseSeatsRelation->first());
$query->whereNotNull('assigned_to') if ($this->assignedCount->first()) {
->orWhereNotNull('asset_id'); return $this->assignedCount->first()->count;
}) }
->count();
return 0;
} }
public function remaincount() public function remaincount()
{ {
$total = $this->totalSeatsByLicenseID(); $total = $this->licenseSeatsCount;
$taken = $this->assignedcount(); $taken = $this->assigned_seats;
$diff = ($total - $taken); $diff = ($total - $taken);
return $diff; return $diff;
} }
@ -156,7 +180,7 @@ class License extends Depreciable
*/ */
public function totalcount() public function totalcount()
{ {
$avail = $this->availcount(); $avail = $this->availSeatsCount;
$taken = $this->assignedcount(); $taken = $this->assignedcount();
$diff = ($avail + $taken); $diff = ($avail + $taken);
return $diff; return $diff;

View file

@ -47,6 +47,21 @@ class Supplier extends Model
protected $fillable = ['name']; protected $fillable = ['name'];
// Eager load counts.
// We do this to eager load the "count" of seats from the controller. Otherwise calling "count()" on each model results in n+1
public function assetsRelation()
{
return $this->hasMany(Asset::class)->whereNull('deleted_at')->selectRaw('supplier_id, count(*) as count')->groupBy('supplier_id');
}
public function getLicenseSeatsCountAttribute()
{
if ($this->licenseSeatsRelation->first()) {
return $this->licenseSeatsRelation->first()->count;
}
return 0;
}
public function assets() public function assets()
{ {
return $this->hasMany('\App\Models\Asset', 'supplier_id'); return $this->hasMany('\App\Models\Asset', 'supplier_id');
@ -59,7 +74,11 @@ class Supplier extends Model
public function num_assets() public function num_assets()
{ {
return $this->hasMany('\App\Models\Asset', 'supplier_id')->count(); if ($this->assetsRelation->first()) {
return $this->assetsRelation->first()->count;
}
return 0;
} }
public function licenses() public function licenses()
@ -69,7 +88,7 @@ class Supplier extends Model
public function num_licenses() public function num_licenses()
{ {
return $this->hasMany('\App\Models\License', 'supplier_id')->count(); return $this->licenses()->count();
} }
public function addhttp($url) public function addhttp($url)