0
$projects = Project::find(collect(request()->get('projects'))->pluck('id')); // collect(...)->pluck('id') is [2, 1]
$projects->pluck('id'); // [1, 2]

I want the result to be in the original order. How do I achieve this?

Joshua Leung
  • 2,219
  • 7
  • 29
  • 52

3 Answers3

0

Try $projects->order_by("updated_at")->pluck("id"); or "created_at" if that's the column you need them ordered by.

latr.88
  • 849
  • 5
  • 17
  • I am implement a draggable-sortable feature, users can sort projects by drag & drop. The data I get from request() is the order of the projects. Therefore I need to adhere to the original order. – Joshua Leung Aug 29 '18 at 19:10
  • 1
    I assume you have a column to save the order then right? Then use that column in the order_by function – latr.88 Aug 29 '18 at 19:39
0

Referencing MySQL order by field in Eloquent and MySQL - SELECT ... WHERE id IN (..) - correct order You can pretty much get the result and have it order using the following:

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

@Jonas raised my awareness to a potential sql injection vulnerability, so I suggest an alternative:

$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);

The explanation to the above is this:

Create a comma separated placeholder '?', for the number of items in the array to serve as named binding (including the column 'id').

  • This is vulnerable to SQL injections. You have to use something like `$projects_ids = array_map('intval', request()->get('projects'));`. – Jonas Staudenmeir Aug 29 '18 at 19:43
0

I solve this by querying the data one by one instead mass query.

$ids = collect(request()->get('projects'))->pluck('id');

foreach($ids as $id){
    $projects[] = Project::find($id);
}

$projects = collect($projects);
$projects->pluck('id');

I have to do this manually because laravel collection maps all the element sorted by using ids.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Azahar Alam
  • 708
  • 5
  • 16