Laravel, объедините два запроса в один - PullRequest
0 голосов
/ 08 октября 2019

Как я мог бы сделать код лучше, чем этот:

$data1 = UploadsPois::where('estado_carga', Util::UPLOAD_POIS_CARGA_INGRESADA)
    ->where('schema_country', $schema_country)
    ->orderBy('id', 'asc')
    ->get();

foreach ($data1 as $carga) {
    $carga->UserResponsable = User::findOrFail($carga->responsable);
    $carga->Pois            = Pois::where('upload_pois_id', $carga->id)->where('pois_validate', Util::POIS_INGRESADO)->orderBy('id', 'asc')->get();
    $carga->Log = LogsPois::where('upload_pois_id', $carga->id)
        ->where('schema_country', $schema_country)
        ->whereNull('address_id')
        ->orderBy('id', 'desc')
        ->first();
}
$tareas['data1'] = $data1;

// All this bucle takes ~13000 miliseconds

$data2 = UploadsPois::where('estado_carga', Util::UPLOAD_POIS_CARGA_DEVUELTA_REVISION)
    ->where('schema_country', $schema_country)
    ->where('revisado_por', \Auth::user()->id)
    ->orderBy('id', 'asc')
    ->get();

foreach ($data2 as $carga) {
    $carga->UserResponsable = User::findOrFail($carga->responsable);
    $carga->UserValidador   = User::findOrFail($carga->validado_por);
    $carga->Pois            = Pois::where('upload_pois_id', $carga->id)->where('pois_validate', Util::POIS_INGRESADO)->orderBy('id', 'asc')->get();
    $carga->Log             = LogsPois::where('upload_pois_id', $carga->id)
        ->where('schema_country', $schema_country)
        ->whereNull('address_id')
        ->orderBy('id', 'desc')
        ->first();
}
$tareas['data2'] = $data2;

// And this one takes ~ 20 or 50 miliseconds

Эти булавы практически одинаковы, как я могу объединить один единственный foreach и один единственный вызов модели UploadsPois? Я не уверен, как я мог установить $tareas['data1'] и $tareas['data2'] в одном процессе.

1 Ответ

1 голос
/ 08 октября 2019

Глядя на этот код, я могу сказать, что есть 4 важные модели: UploadsPois, User, Pois, LogPois.

Вы можете установить отношения для загрузки всех этих данных безнеобходимость в цикле.

См. Красноречивые отношения , Красноречивые отношения: готовность к загрузке

# UploadPois model
namespace App;

use Illuminate\Database\Eloquent\Model;
use User;
use Pois;
use LogsPois;

class UploadsPois extends Model
{
    public function user_responsable()
    {
        return $this->belongsTo(User::class, 'responsable');
    }

    public function user_validador()
    {
        return $this->belongsTo(User::class, 'validado_por');
    }

    public function pois()
    {
        return $this->hasMany(Pois::class, 'upload_pois_id');
    }

    public function log()
    {
        return $this->hasMany(LogsPois::class, 'upload_pois_id');
    }
}

Вы также можете определить обратную связь какследует.

# User model
namespace App;

// Usually User model extends this instead of base model.
use Illuminate\Foundation\Auth\User as Authenticatable;
use UploadsPois;

class User extends Authenticatable
{
    public function responsable_uploads_pois()
    {
        return $this->hasMany(UploadsPois::class, 'responsable');
    }

    public function validador_uploads_pois()
    {
        return $this->hasMany(UploadsPois::class, 'validado_por');
    }
}
# Pois model
namespace App;

use Illuminate\Database\Eloquent\Model;
use UploadsPois;

class Pois extends Model
{
    public function uploads_pois()
    {
        return $this->belongsTo(UploadsPois::class, 'upload_pois_id');
    }
}
# LogPois model
namespace App;

use Illuminate\Database\Eloquent\Model;
use UploadsPois;

class LogPois extends Model
{
    public function uploads_pois()
    {
        return $this->belongsTo(UploadsPois::class, 'upload_pois_id');
    }
}

Теперь, когда у нас есть все определенные отношения, ваша переменная $data1 может быть получена следующим образом:

UploadsPois::where([
    ['estado_carga', Util::UPLOAD_POIS_CARGA_INGRESADA],
    ['schema_country', $schema_country]
])
->with([
    'user_responsable',
    'pois' => function ($pois) {
        $pois->where('pois_validate', Util::POIS_INGRESADO);
    },
    'log' => function ($log) use ($schema_country) {
        $log->where('schema_country', $schema_country)
        ->whereNull('address_id')
        ->orderBy('id', 'desc');
    }
])
->orderBy('id', 'asc')
->get();

как для $data2:

UploadsPois::where([
    ['estado_carga', Util::UPLOAD_POIS_CARGA_DEVUELTA_REVISION],
    ['schema_country', $schema_country],
    ['revisado_por', auth()->id()] //Same as \Auth::id(), same as \Auth::user()->id
])
->with([
    'user_responsable',
    'user_validador',
    'pois' => function ($pois) {
        $pois->where('pois_validate', Util::POIS_INGRESADO)
    },
    'log' => function ($log) use ($schema_country) {
        $log->where('schema_country', $schema_country)
        ->whereNull('address_id')
        ->orderBy('id', 'desc');
    }
])
->orderBy('id', 'asc')
->get();

Соглашения об именах Laravel диктуют ваши методы отношений должны быть в snake_case.

О комбинировании этих запросов. Единственные различия, которые я вижу, следующие:

  • $data1 имеет estado_carga, равный Util::UPLOAD_POIS_CARGA_INGRESADA, тогда как $data2 имеет estado_carga, равный Util::UPLOAD_POIS_CARGA_DEVUELTA_REVISION
  • *У 1042 * есть дополнительный фильтр (validado_por равен аутентифицированному пользователю id)
  • $data2 имеет дополнительные загруженные отношения (user_validador)

Если вы действительно хотитеЕсли вы хотите объединить запросы, вы можете просто не фильтровать по этим двум условиям.

$data = UploadsPois::where('schema_country', $schema_country)
->with([
    'user_responsable',
    'user_validador',
    'pois' => function ($pois) {
        $pois->where('pois_validate', Util::POIS_INGRESADO)
    },
    'log' => function ($log) use ($schema_country) {
        $log->where('schema_country', $schema_country)
        ->whereNull('address_id')
        ->orderBy('id', 'desc');
    }
])
->orderBy('id', 'asc')
->get();

Возвращает коллекцию, которую можно затем отфильтровать, используя различные методы (where, firstWhere, filter, reject и т. Д.)

# data1
$data->where('estado_carga', Util::UPLOAD_POIS_CARGA_INGRESADA);
# data2
$data->where('estado_carga', Util::UPLOAD_POIS_CARGA_DEVUELTA_REVISION)->where('validado_por', auth()->id());

См. Коллекции: Доступные методы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...