Tengo un modelo Eloquent que tiene un modelo relacionado:
public function option() {
return $this->hasOne('RepairOption', 'repair_item_id');
}
public function setOptionArrayAttribute($values)
{
$this->option->update($values);
}
Cuando creo el modelo, no necesariamente tiene un modelo relacionado. Cuando lo actualizo, podría agregar una opción, o no.
Por lo tanto, debo verificar si existe el modelo relacionado, para actualizarlo o crearlo, respectivamente:
$model = RepairItem::find($id);
if (Input::has('option')) {
if (<related_model_exists>) {
$option = new RepairOption(Input::get('option'));
$option->repairItem()->associate($model);
$option->save();
$model->fill(Input::except('option');
} else {
$model->update(Input::all());
}
};
¿Dónde <related_model_exists>está el código que estoy buscando?

Respuestas:
En php 7.2+ no se puede usar
counten el objeto de relación, por lo que no hay un método único para todas las relaciones. Utilice el método de consulta en su lugar como @tremby proporcionado a continuación:solución genérica que funciona en todos los tipos de relación ( pre php 7.2 ):
Esto funcionará para cada relación ya que las propiedades dinámicas regresan
ModeloCollection. Ambos implementanArrayAccess.Entonces va así:
relaciones individuales:
hasOne/belongsTo/morphTo/morphOnerelaciones de muchos:
hasMany/belongsToMany/morphMany/morphToMany/morphedByManyfuente
count($relation)Es una solución general para todas las relaciones. Funcionará paraModelyCollection, aunqueModelno tiene ningún->count()método.Collectiontiene su propio métodoisEmpty, pero laemptyfunción genérica devuelve falso para un objeto (por lo tanto, no funcionará para una colección vacía).count($model->relation)no funcionómorphTocuando la relación aún no tenía una asociación establecida. La identificación y el tipo externos son nulos y la consulta de db creada por Laravel es falsa y genera una excepción. Solía$model->relation()->getOtherKey()como una solución alternativa.count(): Parameter must be an array or an object that implements CountableUn objeto de relación pasa llamadas de métodos desconocidos a un generador de consultas elocuente , que está configurado para seleccionar solo los objetos relacionados. Ese generador a su vez pasa llamadas de métodos desconocidos a su generador de consultas subyacente .
Esto significa que puede usar los métodos
exists()ocount()directamente desde un objeto de relación:Tenga en cuenta los paréntesis después de
relation:->relation()es una llamada a la función (obtener el objeto de relación), en lugar de->relationque Laravel configure un captador de propiedades mágicas para usted (obtener el objeto / objetos relacionados).Usar el
countmétodo en el objeto de relación (es decir, usar los paréntesis) será mucho más rápido que hacerlo$model->relation->count()ocount($model->relation)(a menos que la relación ya se haya cargado con entusiasmo) ya que ejecuta una consulta de conteo en lugar de extraer todos los datos de cualquier objeto relacionado de la base de datos, solo para contarlos. Del mismo modo, el usoexiststampoco necesita extraer datos del modelo.Tanto
exists()ycount()el trabajo en todos los tipos de relación que he probado, así que al menosbelongsTo,hasOne,hasMany, ybelongsToMany.fuente
Prefiero usar el
existsmétodo:RepairItem::find($id)->option()->exists()para verificar si el modelo relacionado existe o no. Está funcionando bien en Laravel 5.2
fuente
Después de Php 7.1 , la respuesta aceptada no funcionará para todo tipo de relaciones.
Porque dependiendo del tipo de relación, Eloquent devolverá a
Collection, aModeloNull. Y en Php 7.1count(null)lanzará unerror.Entonces, para verificar si existe la relación, puede usar:
Para relaciones individuales: por ejemplo
hasOneybelongsToPara relaciones múltiples: Por ejemplo:
hasManyybelongsToManyfuente
No estoy seguro de si esto ha cambiado en Laravel 5, pero la respuesta aceptada usando
count($data->$relation)no funcionó para mí, ya que el solo hecho de acceder a la propiedad de relación causó que se cargara.Al final, un sencillo me
isset($data->$relation)sirvió.fuente
$data->relationsin$(no se puede editar, debido al límite de 6 caracteres)$relation, sería el nombre de su relación, tal$data->postso cual. Lo siento si eso fue confuso, quería dejar en claro querelationno era una propiedad modelo concreta: PSe puede utilizar el relationLoaded método en el objeto del modelo. Esto salvó mi tocino, así que espero que ayude a alguien más. Me dieron esta sugerencia cuando hice la misma pregunta sobre Laracasts.
fuente
Como Hemerson Varela ya dijo en Php 7.1
count(null)arrojará unerroryhasOneregresanullsi no existe una fila. Ya que tienes unhasOnerelación, usaría elemptymétodo para verificar:Pero esto es superfluo. No es necesario verificar si la relación existe, para determinar si debe hacer una
updateo unacreatellamada. Simplemente use el método updateOrCreate . Esto es equivalente a lo anterior:fuente
Tuve que refactorizar completamente mi código cuando actualicé mi versión de PHP a 7.2+ debido al mal uso de la función de conteo ($ x). Esto es un verdadero dolor y también es extremadamente aterrador, ya que hay cientos de usos, en diferentes escenarios y no hay reglas para todos.
Reglas que seguí para refactorizar todo, ejemplos:
$ x = Auth :: user () -> posts-> find (6); (verifique si el usuario tiene un id de publicación = 6 usando -> find ())
$ x = Auth :: usuario () -> perfil-> departamentos; (verifique si el perfil tiene algunos departamentos, puede haber muchos departamentos)
$ x = Auth :: user () -> perfil-> get (); (verifique si el usuario tiene un perfil después de usar un -> get ())
Espero que esto pueda ayudar, incluso 5 años después de que se haya hecho la pregunta, ¡esta publicación de stackoverflow me ha ayudado mucho!
fuente