Klaaz
En un modelo de usuario (tabla con 4 registros), cuando hago:
$coll = User::all();
echo $coll->count();
Obtengo la cantidad de registros encontrados (4).
Pero cuando lo hago:
$coll = User::find(2);
echo $coll->count();
No obtengo 1 (como esperaba) sino la cantidad de atributos en la colección resultante (23 en este caso).
¿Cómo puedo verificar si se encuentran más de un registro?
ACTUALIZAR:
OK, gracias a todos ustedes, ahora veo la diferencia en el resultado entre la colección y el modelo.
Pero mi verdadero problema es que tengo que detectar si estoy teniendo como resultado un modelo o una colección. Dependiendo de este resultado, realizo algunos cambios en el contenido de los campos en los elementos (con mapa ()) o modelo. ¿Cómo puedo detectar si el resultado es un modelo o una colección?
if(count($coll) > 1)
Funciona, pero ¿es este el enfoque correcto?
Bogdán
Esto es lo que está pasando con el código que tienes allí:
1. al llamar User::all()
obtendrás un Illuminate\Database\Eloquent\Collection
en el que puedes llamar count
que cuenta los elementos de la colección así:
public function count()
{
return count($this->items);
}
Esto devolverá la cantidad de elementos en la colección como esperaba correctamente.
2. al llamar User::find(2)
sin embargo, Eloquent Query Builder no devolverá un Collection
porque comprobará a ver cuantos resultados hay, y ya que pasaste una identificación obtendrás como máximo un resultado, por lo que devolverá un Modelo Elocuente en su lugar. El modelo no tiene count()
método, por lo que cuando intenta llamar $coll->count();
irá a la magia __call
método que la clase ha implementado que se ve así:
public function __call($method, $parameters)
{
if (in_array($method, array('increment', 'decrement')))
{
return call_user_func_array(array($this, $method), $parameters);
}
$query = $this->newQuery();
return call_user_func_array(array($query, $method), $parameters);
}
Como puede ver, el método intenta ver si debe llamar a un par de métodos codificados (increment
y decrement
), que por supuesto no coinciden en este caso porque $method = 'count'
por lo que continúa creando una nueva consulta en la que llamará al count
método.
La conclusión es que tanto la primera como la segunda muestra de código terminan haciendo lo mismo: contando todas las entradas en el users
mesa.
Y dado que, como señalé anteriormente, una identificación no puede coincidir con más de una fila (dado que las identificaciones son únicas), el respuesta a tu pregunta es que no hay necesidad ni forma de contar los resultados de find(2)
ya que solo puede ser 0 (si null
se devuelve) o 1 (si se Model
es regresado).
ACTUALIZAR
En primer lugar, para futuras referencias, puede utilizar PHP get_class
para determinar el nombre de clase de un objeto o get_parent_class
para determinar la clase que se está extendiendo. En tu caso la segunda función get_parent_class
podría ser útil para determinar la clase del modelo ya que el User
class extiende una clase de modelo abstracto de Laravel.
Así que si tienes un modelo get_class($coll)
reportará User
pero get_parent_class($coll)
reportará \Illuminate\Database\Eloquent\Model
.
Ahora para verificar si el resultado es una Colección o un Modelo que puede usar instanceof
:
instanceof
se utiliza para determinar si una variable de PHP es un objeto instanciado de una determinada clase
Sus cheques deberían verse así:
// Check if it's a Collection
if ($coll instanceof \Illuminate\Support\Collection)
// Check if it's a Model
if ($coll instanceof \Illuminate\Database\Eloquent\Model)
También es posible que desee comprobar si el resultado es null
desde find
regresará null
si no se encuentra ninguna entrada con el ID dado:
if (is_null($coll))
-
¡Por supuesto! No hice la diferencia entre una colección y un modelo. ¡Gracias por aclararme esto! Consulte la pregunta actualizada para conocer la solución real que estoy buscando.
– Klaaz
12 de mayo de 2015 a las 7:49
-
@Klaaz Actualicé la respuesta con la solución a su pregunta actualizada.
– Bogdán
12 de mayo de 2015 a las 9:12
-
¡Excelente! Esto deja las cosas muy claras, gracias por explicar 🙂
– Klaaz
12 mayo 2015 a las 10:36
-
El
Collection
tiene su propio método$collection->count()
– Código para la vida
28/09/2022 a las 15:41
Parece que estás esperando la método find() comportarse de manera diferente. Desde el documentos
Find a model by its primary key.
-
Laravel rompió muchos enlaces de documentación durante un rediseño en algún momento, por lo que estos enlaces API antiguos están muertos.
– kjones
21 de julio de 2021 a las 20:10
Si su problema es comprobando si es de colección. ¿Por qué no lo compruebas si es de Illuminate\Database\Eloquent\Collection?
if (get_class($coll) == 'Illuminate\Database\Eloquent\Collection') {
your code...
}
o
if ($coll instanceof \Illuminate\Database\Eloquent\Collection) {
your code...
}
no creo
::find()
devuelve una colección, en realidad.– No entrar en pánico
11 mayo 2015 a las 22:56
@Don’tPanic En realidad, puede, si le pasa una serie de identificaciones. Pero en este caso si la entrada con un
id = 2
se encuentra, devolverá un modelo elocuente.– Bogdán
11 mayo 2015 a las 22:57
@Bogdan, Buen punto. Supongo que debería haber dicho más específicamente
::find(2)
no devuelve una colección.– No entrar en pánico
11 mayo 2015 a las 22:59