Open zliebersbach opened 4 months ago
@zliebersbach Encontré una posible solución mientras se soluciona, no se si es la mejor forma:
Creas un trait en app/Traits/EloquentWhereHas.php
<?php
namespace App\Traits;
use MongoDB\BSON\ObjectId;
use Illuminate\Http\Response;
trait EloquentWhereHas{
public function scopeWhereHasTemp($query, $relation, $cb)
{
$relationInstance = $this->$relation();
$relatedModelQuery = $relationInstance->getRelated()->newQuery();
call_user_func($cb, $relatedModelQuery);
if ($relationInstance instanceof \Illuminate\Database\Eloquent\Relations\BelongsTo) {
$foreignKey = $relationInstance->getForeignKeyName();
$parentKey = $relationInstance->getOwnerKeyName();
} else {
$foreignKey = $relationInstance->getLocalKeyName();
$parentKey = $relationInstance->getForeignKeyName();
}
if($foreignKey == 'id') $foreignKey = "_id";
$objectIds = $relatedModelQuery->pluck($parentKey)->toArray();
// Agregar si es necesario
/* $objectIds = array_map(function ($id) {
return new ObjectId($id);
}, $objectIds); */
$query->whereIn($foreignKey, $objectIds);
return $query;
}
}
Usas el trait en el modelo dentro de la clase:
use App\Traits\EloquentWhereHas;
class MiModelo extends Model {
use EloquentWhereHas;
public $collection = "mimodelo";
....
En tu consulta
MiModelo::whereHasTemp('nameRelation', function($query) { $query->where('status', true);})->get()
En conclusión
Revisando el Log, la diferencia es que cambia el "id" por "_id", ejemplo log:
con whereHas
{"id":{"$in":["641a45c05908a72267057c3f"]}}
con el trait "whereHasTemp"
{"_id":{"$in":["641a45c05908a72267057c3f"]}}
Description:
Cannot use whereHas on relations that use ObjectId. ObjectId is the best-practice method for storing related document IDs.
Loading the relation works as expected, but not whereHas.
If this is possible, I propose adding the solution to the documentation, otherwise a fix should be introduced.
Steps to reproduce
EntityB
has the following relation configured:EntityB::whereHas('entityA', fn ($query) => $query->where('status', Status::ADDED))->get()
Expected behaviour
The following query should be executed (collected from
DB::getQueryLog()
):Actual behaviour
The following query is executed (collected from
DB::getQueryLog()
):Logs: