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, il n'a pas nécessairement de modèle associé. Lorsque je le mets à jour, je peux ajouter une option, ou pas.
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.
Réponses:
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 plutôt la méthode de requête comme @tremby fourni ci-dessous:solution générique fonctionnant sur tous les types de relations ( pré php 7.2 ):
Cela fonctionnera pour chaque relation puisque les propriétés dynamiques renvoient
Model
ouCollection
. Les deux implémententArrayAccess
.Donc ça va comme ça:
relations uniques:
hasOne
/belongsTo
/morphTo
/morphOne
relations à plusieurs:
hasMany
/belongsToMany
/morphMany
/morphToMany
/morphedByMany
la source
count($relation)
est une solution générale pour toutes les relations. Cela fonctionnera pourModel
etCollection
, alors qu'ilModel
n'y a pas de->count()
méthode.Collection
a sa propre méthodeisEmpty
, mais laempty
fonction générique renvoie false pour un objet (donc ne fonctionnera pas pour une collection vide).count($model->relation)
n'a pas fonctionnémorphTo
lorsque la relation n'avait pas encore d'association. L'ID et le type étrangers sont nuls et la requête db construite par Laravel est fausse et augmente l'exception. J'ai utilisé$model->relation()->getOtherKey()
comme solution de contournement.count(): Parameter must be an array or an object that implements Countable
Un objet Relation transmet des appels de méthode inconnus à un générateur de requêtes Eloquent , qui est configuré pour sélectionner uniquement les objets associés. Ce générateur transmet à son tour les appels de méthode inconnus à son générateur de requêtes sous-jacent .
Cela signifie que vous pouvez utiliser les méthodes
exists()
oucount()
directement à partir d'un objet de relation:Notez les parenthèses après
relation
:->relation()
est un appel de fonction (obtenant l'objet de relation), par opposition à->relation
un getter de propriété magique configuré pour vous par Laravel (obtenant l'objet / les objets associés).L'utilisation de la
count
méthode sur l'objet de relation (c'est-à-dire l'utilisation des parenthèses) sera beaucoup plus rapide que de faire$model->relation->count()
oucount($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, l'utilisationexists
n'a pas non plus besoin d'extraire les données du modèle.Les deux
exists()
et lecount()
travail sur tous les types de relations que j'ai essayé, donc au moinsbelongsTo
,hasOne
,hasMany
etbelongsToMany
.la source
Je préfère utiliser la
exists
méthode:RepairItem::find($id)->option()->exists()
pour vérifier si le modèle associé existe ou non. Cela fonctionne bien sur Laravel 5.2
la source
Après Php 7.1 , la réponse acceptée ne fonctionnera pas pour tous les types de relations.
Parce que selon le type de relation, Eloquent retournera un
Collection
, unModel
ouNull
. Et dans Php 7.1count(null)
jettera un fichiererror
.Donc, pour vérifier si la relation existe, vous pouvez utiliser:
Pour les relations uniques: par exemple
hasOne
etbelongsTo
Pour les relations multiples: Par exemple:
hasMany
etbelongsToMany
la source
Je ne sais pas si cela a changé dans Laravel 5, mais la réponse acceptée en utilisant
count($data->$relation)
n'a pas fonctionné pour moi, car l'acte même d'accéder à la propriété relation a provoqué son chargement.En fin de compte, un simple a
isset($data->$relation)
fait l'affaire pour moi.la source
$data->relation
sans$
(impossible de modifier, à cause de la limite de 6 caractères)$relation
serait le nom de votre relation, tel$data->posts
ou tel. Désolé si cela prêtait à confusion, je voulais préciser que cerelation
n'était pas une propriété modèle en béton: PVous 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'ai reçu cette suggestion lorsque j'ai posé la même question sur les Laracasts.
la source
Comme Hemerson Varela l'a déjà dit dans Php 7.1
count(null)
lancera unerror
ethasOne
retourneranull
si aucune ligne n'existe. Puisque vous avez unehasOne
relation, j'utiliserais laempty
méthode pour vérifier:Mais c'est superflu. Il n'est pas nécessaire de vérifier si la relation existe, pour déterminer si vous devez faire un
update
ou uncreate
appel. Utilisez simplement la méthode updateOrCreate . Ceci est équivalent à ce qui précède:la source
J'ai dû refactoriser complètement mon code lorsque j'ai mis à jour ma version PHP vers 7.2+ en raison d'une mauvaise utilisation de la fonction count ($ x). C'est une vraie douleur et c'est aussi extrêmement effrayant car il y a des centaines d'utilisations, dans différents scénarios et il n'y a pas de règles uniques pour tous.
Règles que j'ai suivies pour tout refactoriser, exemples:
$ x = Auth :: user () -> posts-> find (6); (vérifiez si l'utilisateur a un post id = 6 en utilisant -> find ())
$ x = Auth :: user () -> profile-> départements; (vérifier si le profil a certains départements, il peut y avoir de nombreux départements)
$ x = Auth :: user () -> profile-> get (); (vérifiez si l'utilisateur a un profil après avoir utilisé un -> get ())
J'espère que cela peut aider, même 5 ans après que la question ait été posée, ce post de stackoverflow m'a beaucoup aidé!
la source