J'ai un modèle Eloquent qui a un modèle connexe:
public function option() {
return $this->hasOne('RepairOption', 'repair_item_id');
}
public function setOptionArrayAttribute($values)
{
$this->option->update($values);
}
Lorsque je crée le modèle, celui-ci n’a pas nécessairement de modèle associé. Lorsque je le met à jour, je peux ajouter une option ou non.
Je dois donc vérifier si le modèle associé existe, pour le mettre à jour ou le créer, respectivement:
$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());
}
};
Où <related_model_exists>
est le code que je recherche.
Dans php 7.2+ vous ne pouvez pas utiliser count
sur l'objet relation, il n'y a donc pas de méthode unique pour toutes les relations. Utilisez la méthode de requête à la place de @tremby ci-dessous:
$model->relation()->exists()
solution générique travaillant sur tous les types de relations ( pre php 7.2 ):
if (count($model->relation))
{
// exists
}
Cela fonctionnera pour toutes les relations car les propriétés dynamiques renvoient Model
ou Collection
. Les deux implémentent ArrayAccess
.
Alors ça va comme ça:
relations uniques: hasOne
/belongsTo
/morphTo
/morphOne
// no related model
$model->relation; // null
count($model->relation); // 0 evaluates to false
// there is one
$model->relation; // Eloquent Model
count($model->relation); // 1 evaluates to true
à-plusieurs relations: hasMany
/belongsToMany
/morphMany
/morphToMany
/morphedByMany
// no related collection
$model->relation; // Collection with 0 items evaluates to true
count($model->relation); // 0 evaluates to false
// there are related models
$model->relation; // Collection with 1 or more items, evaluates to true as well
count($model->relation); // int > 0 that evaluates to true
Un objet Relation transmet les appels de méthodes inconnus à un constructeur de requêtes Eloquent , configuré pour ne sélectionner que les objets liés. Ce générateur transmet à son tour les appels de méthodes inconnus à its sous-jacent query Builder .
Cela signifie que vous pouvez utiliser les méthodes exists()
ou count()
directement à partir d'un objet de relation:
$model->relation()->exists(); // bool: true if there is at least one row
$model->relation()->count(); // int: number of related rows
Notez les parenthèses après relation
: ->relation()
est un appel de fonction (obtenir l'objet relation), par opposition à ->relation
pour lequel un getter de propriétés magiques a été configuré pour vous par Laravel (pour obtenir l'objet/les objets associés).
L'utilisation de la méthode count
sur l'objet relation (c'est-à-dire, l'utilisation des parenthèses) sera beaucoup plus rapide que l'exécution de $model->relation->count()
ou count($model->relation)
(sauf si la relation a déjà été chargée avec impatience) car elle exécute une requête de comptage plutôt que d'extraire toutes les données pour tous les objets liés de la base de données, juste pour les compter. De même, utiliser exists
n'a pas non plus besoin d'extraire les données de modèle.
exists()
et count()
fonctionnent sur tous les types de relation que j'ai essayés, donc au moins belongsTo
, hasOne
, hasMany
et belongsToMany
.
Après Php 7.1 , la réponse acceptée ne fonctionnera pas pour tous les types de relations.
En fonction du type de relation, Eloquent renverra un Collection
, un Model
ou un Null
. Et dans Php 7.1 count(null)
lancera un error
.
Donc, pour vérifier si la relation existe, vous pouvez utiliser:
Pour les relations simples: Par exemple, hasOne
et belongsTo
if(!is_null($model->relation)) {
....
}
Pour les relations multiples: Par exemple: hasMany
et belongsToMany
if ($model->relation->isNotEmpty()) {
....
}
Pas sûr que cela ait changé dans Laravel 5, mais la réponse acceptée utilisant count($data->$relation)
n'a pas fonctionné pour moi, car l'acte même d'accéder à la propriété de relation a provoqué son chargement.
À la fin, un isset($data->$relation)
simple a fait l'affaire pour moi.
Vous pouvez utiliser la méthode relationLoaded sur l'objet de modèle. Cela a sauvé mon bacon alors j'espère que cela aidera quelqu'un d'autre. J'étais vu cette suggestion quand j'ai posé la même question sur Laracasts.
Comme Hemerson Varela l'a déjà dit dans Php 7.1, count(null)
lève une variable error
et hasOne
renvoie null
si aucune ligne n'existe. Puisque vous avez une relation hasOne
, j'utiliserais la méthode empty
pour vérifier:
$model = RepairItem::find($id);
if (!empty($temp = $request->input('option'))) {
$option = $model->option;
if(empty($option)){
$option = $user->expertise()->create();
}
$option->someAttribute = temp;
$option->save();
};
Vous avez dit que vous voulez vérifier si la relation existe déjà, vous pouvez donc faire un update
ou create
. Cependant, cela n'est pas nécessaire, à cause de la méthode updateOrCreate .
Faites juste ceci:
$model = RepairItem::find($id);
$model->option()
->updateOrCreate(['repair_item_id' => $model->id],['option' => 'A']);