【问题标题】:Laravel query builder. How to make the query shorter?Laravel 查询生成器。如何使查询更短?
【发布时间】:2020-12-25 07:35:18
【问题描述】:

我需要为数据表准备数据,并且我需要计算查询的过滤数据总量,但由于限制,我不能只用一个查询来完成,所以我必须做几乎相同的查询,但要使用分页没有限制选项,它使我的代码量 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);

}

【问题讨论】:

    标签: laravel laravel-query-builder


    【解决方案1】:

    如果您认为需要这两个查询,您可以保留与构建器相同的查询部分并从中运行两个查询:

    $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() 来获取计数

    【讨论】:

      【解决方案2】:

      您可以使用 clone 复制查询,然后使用不同的 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();
      

      【讨论】:

        猜你喜欢
        • 2015-12-13
        • 1970-01-01
        • 1970-01-01
        • 2018-09-28
        • 2013-05-30
        • 1970-01-01
        • 2017-03-29
        • 2018-07-03
        相关资源
        最近更新 更多