Ich habe ein eloquentes Modell, das ein verwandtes Modell hat:
public function option() {
return $this->hasOne('RepairOption', 'repair_item_id');
}
public function setOptionArrayAttribute($values)
{
$this->option->update($values);
}
Wenn ich das Modell erstelle, muss es nicht unbedingt ein verwandtes Modell haben. Wenn ich es aktualisiere, kann ich eine Option hinzufügen oder nicht.
Ich muss also überprüfen, ob das zugehörige Modell vorhanden ist, um es entweder zu aktualisieren oder zu erstellen:
$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());
}
};
Wo <related_model_exists>
ist der Code, den ich suche?
Antworten:
In PHP 7.2+ können Sie nicht
count
für das Beziehungsobjekt verwenden, daher gibt es keine Einheitsmethode für alle Beziehungen. Verwenden Sie stattdessen die unten angegebene Abfragemethode als @tremby:generische lösung für alle beziehungstypen ( vor php 7.2 ):
Dies funktioniert für jede Beziehung, da dynamische Eigenschaften
Model
oder zurückgebenCollection
. Beide implementierenArrayAccess
.So geht es also:
Einzelbeziehungen:
hasOne
/belongsTo
/morphTo
/morphOne
zu viele Beziehungen:
hasMany
/belongsToMany
/morphMany
/morphToMany
/morphedByMany
quelle
count($relation)
ist eine allgemeine Lösung für alle Beziehungen. Es wird fürModel
und funktionierenCollection
, obwohlModel
es keine->count()
Methode gibt.Collection
hat eine eigene MethodeisEmpty
, aber die generischeempty
Funktion gibt false für ein Objekt zurück (funktioniert daher nicht für leere Sammlungen).count($model->relation)
hat nicht funktioniert,morphTo
wenn für die Beziehung noch keine Zuordnung festgelegt wurde. Fremde ID und Typ sind null und die von Laravel erstellte Datenbankabfrage ist falsch und löst eine Ausnahme aus. Ich habe$model->relation()->getOtherKey()
als Workaround verwendet.count(): Parameter must be an array or an object that implements Countable
Ein Beziehungsobjekt leitet unbekannte Methodenaufrufe an einen Eloquent Query Builder weiter , der so eingerichtet ist, dass nur die zugehörigen Objekte ausgewählt werden. Dieser Builder leitet wiederum unbekannte Methodenaufrufe an den zugrunde liegenden Abfrage-Builder weiter .
Dies bedeutet, dass Sie die Methoden
exists()
odercount()
direkt von einem Beziehungsobjekt aus verwenden können:Beachten Sie die Klammern nach
relation
:->relation()
ist ein Funktionsaufruf (Abrufen des Beziehungsobjekts), im Gegensatz dazu->relation
ein von Laravel für Sie eingerichteter Getter für magische Eigenschaften (Abrufen des zugehörigen Objekts / der zugehörigen Objekte).Die Verwendung der
count
Methode für das Beziehungsobjekt (dh die Verwendung der Klammern) ist viel schneller als die Ausführung$model->relation->count()
odercount($model->relation)
(es sei denn, die Beziehung wurde bereits eifrig geladen), da eine Zählabfrage ausgeführt wird, anstatt alle Daten für verwandte Objekte abzurufen aus der Datenbank, nur um sie zu zählen. Ebenso müssen bei der Verwendungexists
auch keine Modelldaten abgerufen werden.Sowohl
exists()
undcount()
Arbeit für alle Beziehungstypen habe ich versucht, so zumindestbelongsTo
,hasOne
,hasMany
, undbelongsToMany
.quelle
Ich bevorzuge die
exists
Methode:RepairItem::find($id)->option()->exists()
um zu überprüfen, ob ein verwandtes Modell vorhanden ist oder nicht. Es funktioniert gut mit Laravel 5.2
quelle
Nach Php 7.1 funktioniert die akzeptierte Antwort nicht für alle Arten von Beziehungen.
Da Eloquent je nach Typ der Beziehung a
Collection
, aModel
oder zurückgibtNull
. Und in Php 7.1count(null)
wird ein werfenerror
.Um zu überprüfen, ob die Beziehung besteht, können Sie Folgendes verwenden:
Für Beziehungen einzeln: Zum Beispiel
hasOne
undbelongsTo
Für mehrere Beziehungen: Zum Beispiel:
hasMany
undbelongsToMany
quelle
Ich bin mir nicht sicher, ob sich dies in Laravel 5 geändert hat, aber die akzeptierte Antwort mit
count($data->$relation)
hat bei mir nicht funktioniert, da der Zugriff auf die Relation-Eigenschaft dazu führte, dass sie geladen wurde.Am Ende hat ein Unkomplizierter
isset($data->$relation)
den Trick für mich getan.quelle
$data->relation
ohne$
(kann nicht bearbeitet werden, da$relation
wäre der Name Ihrer Beziehung, so$data->posts
oder so. Entschuldigung, wenn das verwirrend war, wollte ich klarstellen, dass esrelation
sich nicht um eine konkrete Modelleigenschaft handelt: PSie können die RelationLoaded- Methode für das Modellobjekt verwenden. Das hat meinen Speck so hoffentlich gerettet, dass es jemand anderem hilft. Ich erhielt diesen Vorschlag, als ich die gleiche Frage zu Laracasts stellte.
quelle
Wie Hemerson Varela bereits in Php 7.1 sagte,
count(null)
wird ein geworfenerror
undhasOne
zurückgegeben,null
wenn keine Zeile existiert. Da Sie einehasOne
Beziehung haben, würde ich dieempty
Methode verwenden, um Folgendes zu überprüfen:Das ist aber überflüssig. Es ist nicht erforderlich zu überprüfen, ob die Beziehung besteht, um festzustellen, ob Sie einen
update
oder einencreate
Anruf tätigen sollten . Verwenden Sie einfach die updateOrCreate- Methode. Dies entspricht dem oben Gesagten:quelle
Ich musste meinen Code komplett überarbeiten, als ich meine PHP-Version auf 7.2+ aktualisierte, weil die Funktion count ($ x) nicht richtig verwendet wurde. Dies ist ein echter Schmerz und auch äußerst beängstigend, da es Hunderte von Anwendungen in verschiedenen Szenarien gibt und es keine Regeln gibt, die für alle geeignet sind.
Regeln, die ich befolgt habe, um alles umzugestalten, Beispiele:
$ x = Auth :: user () -> posts-> find (6); (Überprüfen Sie mit -> find (), ob der Benutzer eine Post-ID = 6 hat.)
$ x = Auth :: user () -> Profil-> Abteilungen; (Überprüfen Sie, ob das Profil einige Abteilungen hat. Es kann viele Abteilungen geben.)
$ x = Auth :: user () -> profile-> get (); (Überprüfen Sie, ob der Benutzer ein Profil hat, nachdem Sie ein -> get () verwendet haben.)
Ich hoffe, dies kann helfen, auch 5 Jahre nachdem die Frage gestellt wurde, hat mir dieser Stackoverflow-Beitrag sehr geholfen!
quelle