使用关系值搜索数据表

Posted

技术标签:

【中文标题】使用关系值搜索数据表【英文标题】:Search datatable with relationship values 【发布时间】:2020-05-14 20:53:20 【问题描述】:

当我需要对我的数据表进行搜索时遇到问题。我有 4 列与另一个表有关系。在我的控制器上我做了一个连接来转换这些数据,所以当我在搜索框上放一些 ID 时,过滤器工作得很好,但我需要让这个搜索只适用于屏幕上显示的数据。

这是我的控制器:

public function revList(Request $request)

    if(auth()->user()->can('Visualizar Revisão'))
        $revisoes = DB::table('revisao_ambientes')
            ->join('unidades', 'revisao_ambientes.unidade_id', '=', 'unidades.id')
            ->join('blocos', 'revisao_ambientes.bloco_id', '=', 'blocos.id')
            ->join('ambientes', 'revisao_ambientes.ambiente_id', '=', 'ambientes.id')
            ->join('users', 'revisao_ambientes.user_id', '=', 'users.id')
            ->select([
                'revisao_ambientes.unidade_id', 'unidades.name as unidade_name', 
                'revisao_ambientes.bloco_id', 'blocos.name as bloco_name', 
                DB::raw('CONCAT(ambientes.sala, " - ", ambientes.name) as ambiente_name'),
                'revisao_ambientes.user_id', 'users.name as user_name', 
                'revisao_ambientes.created_at as created_at',
                'revisao_ambientes.rev_id as rev_id',
            ]);                 

        return datatables()->of($revisoes) 
            ->addColumn('detalhes', function($row) 
                return '<a href="revisao/'. $row->rev_id .'" class="label label-info">Detalhes</a>';
            )
            //Try to make a filter by the building (Don't work)
            ->filterColumn('bloco_name', function($revisoes, $search) 
                $revisoes->where('blocos', 'LIKE', "$search%");
            )
            ->rawColumns(['detalhes'])
            ->make(true);
        else
            return view('errors.401');
         
    

这是我的服务器端数据表脚本:

$(document).ready( function () 
$('#rev-datatable').DataTable(                 
  dom: 'Blfrtip',
      lengthMenu: [
          [10, 25, 50, 100, -1], 
          [10, 25, 50, 100, "Todos"]
        ],
      buttons: [
           extend: 'copy', text: 'Copiar', exportOptions: 
                columns: [ 0, 1, 2, 3, 4 ]
            ,
           extend: 'excel', text: 'Excel', exportOptions: 
                columns: [ 0, 1, 2, 3, 4]
            ,
           extend: 'pdf', text: 'PDF', orientation: 'landscape',
            pageSize: 'LEGAL', exportOptions: 
                columns: [ 0, 1, 2, 3, 4]
            ,             
      ],
      processing: true,
      Filter: true,
      lengthChange: true,
      lengthMenu: [[10, 25, 50, 100, 200, -1], [10, 25, 50, 100, 200, "Todos"]],
      order:[[0,'desc']],
      serverSide: true,
      ajax: " url('/revisao/rev-list') ",
      columns: [
           data: 'created_at', name: 'created_at' ,
           data: 'user_name', name: 'user_id' ,
           data: 'unidade_name', name: 'unidade_id' ,
           data: 'bloco_name', name: 'bloco_id' ,
           data: 'ambiente_name', name: 'ambiente_id' , 
           data: 'detalhes', searchable: false, orderable: false,                 
             ] , 
    );
 );

我需要做些什么才能使它工作?

提前感谢!

【问题讨论】:

【参考方案1】:

我不完全理解这个问题,但我发现您的列数据表选项存在问题。 name 属性定义数据库中列的名称,因此将列更改为:

    columns: [
       data: 'created_at', name: 'revisao_ambientes.created_at' ,
       data: 'user_name', name: 'users.name' ,
       data: 'unidade_name', name: 'unidades.name' ,
       data: 'bloco_name', name: 'blocos.name' ,
       data: 'ambiente_name' , 
       data: 'detalhes', searchable: false, orderable: false,                 
    ] ,

此外,您不需要为 bloco_name 定义 filterColumn,但您需要为ambiente_name 定义它。这就是为什么我在列中删除了ambiente_name 的名称。现在删除 bloco_name 的 filterColumn 并添加:

->filterColumn('ambiente_name', function($revisoes, $search) 
    $sql = "CONCAT(ambientes.sala, ' - ', ambientes.name) like ?";
    $revisoes->whereRaw($sql, ["%$search%"]);
)

由于我们通过参数绑定注入 $search,所以没有 SQL 注入的风险。 另请注意,通过提及数据库列的实际名称,您将泄露有关您的内部数据库结构的信息,这被认为是一个安全漏洞。如果您不关心,那么这就是解决方案,但如果您关心为每一列编写 filterColumn,并从数据表列中删除所有“名称”属性。

【讨论】:

Tks,这正是我所需要的。非常感谢你。我只编辑这一行:** data: 'ambiente_name', name: 'ambientes.name' ,**

以上是关于使用关系值搜索数据表的主要内容,如果未能解决你的问题,请参考以下文章

Laravel:数据表搜索选项不使用关系表字段

不搜索一对多核心数据关系

Laravel 数据表搜索嵌套关系

laravel 7.14 在使用关系搜索数据表后为产品构建链接

如何使用 spatie/laravel-query-builder 过滤/搜索具有关系的数据? (拉拉维尔)

ElasticSearch安装和使用