laravel / nova-issues

557 stars 34 forks source link

Lens CSV export empty when query ID is not the same as resource model ID #4890

Closed moisessepulveda closed 2 years ago

moisessepulveda commented 2 years ago

Description:

When you we have a lens that contains a group by and you try to export data as CSV, it doesn't work when you select individual record. It only works when "Select all" is selected.

This issue only happens when primary key obtained from query does not belongs to the same model as resource.

Detailed steps to reproduce the issue on a fresh Nova installation:

First keep in mind and create the next two models:

Employee:

column type
id integer
name string

Payment:

column type
id integer
amount integer
employee_id integer
employee id name payments
1 jack sparrow 5
2 jane doe 10
3 jhon doe 20

Consider a query like this:

/**
     * Get the query builder / paginator for the lens.
     *
     * @param  \Laravel\Nova\Http\Requests\LensRequest  $request
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return mixed
     */
    public static function query(LensRequest $request, $query)
    {
        return $request->withOrdering($request->withFilters(
            $query->select('employees.id', 'employees.name', DB::raw('count(payments.id) as count'))
            ->join('employees', 'payments.employee_id', '=', 'employees.id')
            ->groupBy('employees.id', 'employees.name')
        ));
    }

fields:


public function fields(NovaRequest $request)
    {
        return [
            ID::make(__('ID'), 'id')->sortable(),
            Text::make('Name', 'name'),
            Number::make('Count', 'count')
        ];
    }

actions:


public function actions(NovaRequest $request)
    {
        return [
            ExportAsCsv::make(__('Exportar a CSV'))->withFormat(function ($model) {
                return [
                    'id' => $model->id,
                    'Name' => $model->name,
                    'Count' => $model->count,
                ];
            })
        ];
    }
crynobone commented 2 years ago

At the moment there's no reliable way to identify resourceIds when Lens query doesn't use the resource default ID https://github.com/laravel/nova/blob/96d4481cfd5bd4406212487e17838fd6bc261f6e/src/Http/Requests/ActionRequest.php#L118-L121 and this wouldn't be an easy fix.

If you can accept to export CSV for "select all" until we can come up with a solution then you can use the following:


    public function lenses(Request $request): array
    {
        return [
            PaymentsPerEmployee::make()->canSee(function ($request) {
                return $request->allResourcesSelected();
            }),
        ];
    }
moisessepulveda commented 2 years ago

Thanks for the answer, I hope you can find a solution soon. I'll stick with the workaround proposal for the moment