【问题标题】:Laravel Model::find() auto sort the results by id, how to stop this?Laravel Model::find() 自动按 id 对结果进行排序,如何停止呢?
【发布时间】:2019-02-04 15:36:02
【问题描述】:
$projects = Project::find(collect(request()->get('projects'))->pluck('id')); // collect(...)->pluck('id') is [2, 1]
$projects->pluck('id'); // [1, 2]

我希望结果是原始顺序。我如何做到这一点?

【问题讨论】:

    标签: laravel


    【解决方案1】:

    试试$projects->order_by("updated_at")->pluck("id");"created_at",如果这是您需要它们排序的列。

    【讨论】:

    • 我正在实现一个可拖动排序的功能,用户可以通过拖放对项目进行排序。我从 request() 得到的数据是项目的顺序。所以我需要遵守原来的顺序。
    • 我假设您有一个列来保存订单,对吧?然后在 order_by 函数中使用该列
    【解决方案2】:

    引用 MySQL order by field in EloquentMySQL - SELECT ... WHERE id IN (..) - correct order 您几乎可以使用以下命令获得结果并对其进行排序:

    $projects_ids = request()->get('projects'); //assuming this is an array
    $projects = Project::orderByRaw("FIELD(id, ".implode(',', projects_ids).")")
        ->find(projects_ids)
        ->pluck('id'));
    

    @Jonas 提高了我对潜在 sql 注入漏洞的认识,因此我建议了一个替代方案:

    $projects_ids = request()->get('projects');
    $items = collect($projects_ids);
    
    $fields = $items->map(function ($ids){
       return '?';
    })->implode(',');
    
    
    $projects = Project::orderbyRaw("FIELD (id, ".$fields.")", $items->prepend('id'))
            ->find($projects_ids);
    

    对上面的解释是这样的:

    创建一个逗号分隔的占位符“?”,用于数组中的项目数作为命名绑定(包括列“id”)。

    【讨论】:

    • 这很容易受到 SQL 注入的攻击。你必须使用$projects_ids = array_map('intval', request()->get('projects'));之类的东西。
    【解决方案3】:

    我通过逐一查询数据而不是批量查询来解决这个问题。

    $ids = collect(request()->get('projects'))->pluck('id');
    
    foreach($ids as $id){
        $projects[] = Project::find($id);
    }
    
    $projects = collect($projects);
    $projects->pluck('id');
    

    我必须手动执行此操作,因为 laravel 集合映射所有使用 id 排序的元素。

    【讨论】:

      猜你喜欢
      • 2018-06-13
      • 2012-07-15
      • 1970-01-01
      • 2018-07-09
      • 1970-01-01
      • 2023-03-15
      • 2018-07-25
      • 2019-12-17
      • 1970-01-01
      相关资源
      最近更新 更多