1

Hello I am using laravel Yajra datatables, the matter is that I have a 2 variables created in a function with the name of the id.

This is all the code

<?php

namespace App\Http\Controllers\Datatables;

use App\User;
use Carbon\Carbon;
use Yajra\DataTables\DataTables;
use App\Reportes;

class ReportesDatatable
{
    public function ReportesDatatable()
    {
        $reportes = Reportes::get();

        return Datatables::of($reportes)
            ->editColumn('reportante', function ($reportes) {
              $reportante = User::find($reportes->reportante);              
              return $reportante->name;             
            })      
            ->editColumn('user_id_afectado', function ($reportes) {
              $nameafectado = User::find($reportes->user_id_afectado);              
              return $nameafectado->name;               
            })      
            ->editColumn('created_at', function ($reportes) {
                return '<span data-popup="tooltip" data-placement="left" title="' . $reportes->timestamp . '">' . $reportes->timestamp . '</span>';
            })
            ->addColumn('action', function ($reportes) {
                return '<div class="btn-group btn-group-justified"> <a href="' . route('admin.get.editUser', $reportes->reportante) . '" class="btn btn-sm btn-secondary mr-2"> Ver Reportante</a> <a href="' . route('admin.get.editUser', $reportes->user_id_afectado) . '" class="btn btn-sm btn-primary mr-2">Afectado</a> <a href="' . route('admin.impersonate', $reportes->user_id_afectado) . '" data-popup="tooltip" data-placement="left" title="Logear como Afectado ' . $reportes->user_id_afectado . '" class="btn btn-sm btn-warning"> <i class="icon-circle-right2 text-white"></i></a></div>';
            })
            ->rawColumns(['role', 'action', 'created_at'])
            ->make(true);

    }
}

The variables that I need to rescue are these. I do this to no longer query the database again. I think what would be the most optimal?

              1.- $reportante = User::find($reportes->reportante);  
              2.- $nameafectado = User::find($reportes->user_id_afectado);  

I need to rescue those 2 variables and put them in the function

            ->addColumn('action', function ($reportes) {
                return '<div class="btn-group btn-group-justified"> <a href="' . route('admin.get.editUser', $reportante) . '" class="btn btn-sm btn-secondary mr-2"> Ver Reportante</a> <a href="' . route('admin.get.editUser', $nameafectado) . '" class="btn btn-sm btn-primary mr-2">Afectado</a> <a href="' . route('admin.impersonate', $reportes->user_id_afectado) . '" data-popup="tooltip" data-placement="left" title="Logear como Afectado ' . $nameafectado . '" class="btn btn-sm btn-warning"> <i class="icon-circle-right2 text-white"></i></a></div>';
            })

The variable would remain in this way with the rescued variables.

Currently if I put the variables they tell me that they do not exist because they are in a different function I think.

How to make those variables global?

2
  • Is the Reportes model setup with a relation to the User model. If you have a relation, then you can use eager loading. If you can add your Reportes model into your question, it may help understand how the relation is. Commented Jul 20, 2021 at 20:50
  • "That's why I need to inherit the variable already created in the previous function." - where is the previous function? Commented Jul 20, 2021 at 20:55

3 Answers 3

2

In a function closure any external variables are not accessible in the function context, you can include the use keyword (Inheriting variables from the parent scope, see https://www.php.net/manual/en/functions.anonymous.php#example-158) to use those variables in a different context

public function ReportesDatatable()
{
    $reportes = Reportes::get();
    $reportante = User::find($reportes->reportante);
    $nameafectado = User::find($reportes->user_id_afectado);
    return Datatables::of($reportes)
        ->editColumn('reportante', function ($reportes) use ($reportante) {
          // $reportante = User::find($reportes->reportante);
          return $reportante->name;             
        })      
        ->editColumn('user_id_afectado', function ($reportes) use ($nameafectado) {
          // $nameafectado = User::find($reportes->user_id_afectado);              
          return $nameafectado->name;               
        })      
        ....
}
Sign up to request clarification or add additional context in comments.

3 Comments

Yes that way it works, but I don't want to overload the server with too many database queries. That's why I need to inherit the variable already created in the previous function.
@NikoBoomer, can you also add the Reportes model to the question to see what relations you have on the model, so we can answer this better? Is there a relation for user on the Reportes model?
@NikoBoomer this should work the way you want. I've commented some lines you don't need. The user queries are performed only once when creating $reportante and $nameafectado. Then you can use them in any internal closures
1
$reportante = User::find($reportes->reportante);
return Datatables::of($reportes)
->editColumn('reportante', function ($reportes) use ($reportante) {
    return $reportante->name;             
})

3 Comments

isn't $reportes a collection? $reportes->reportante wouldn't work.
Yes that way it works, but I don't want to overload the server with too many database queries. That's why I need to inherit the variable already created in the previous function.
@NikoBoomer i don't if that is a question, but you can use use in any function as long as the var you path is in the same context as the fn, so ->addColumn('action', function () use ($reportes, $reportante) { is also valid
0

$reportes is a collection (Reportes::get()) so how is this supposed to work:?

->editColumn('reportante', function ($reportes) {
              $reportante = User::find($reportes->reportante);              
              return $reportante->name;             
            }) 

Let's assume you've set up relations of Reportes model correctly (hasOne reportante and hasOne afectado(?)), then do this query: $reportes = Reportes::with(['reportante', 'afectado'])->get();

and Datatables:

return Datatables::of($reportes)
            //see? single $report, not all $reportes
            ->editColumn('reportante', function ($report) {
              return $report->reportante->name;             
            })
            ->editColumn('user_id_afectado', function ($report) {
              return $report->afectado->name;               
            })
            ->editColumn(....)

1 Comment

Yes that way it works, but I don't want to overload the server with too many database queries. That's why I need to inherit the variable already created in the previous function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.