Ich habe ein eloquentes Modell mit einem verwandten Modell:
public function option() {
return $this->hasOne('RepairOption', 'repair_item_id');
}
public function setOptionArrayAttribute($values)
{
$this->option->update($values);
}
Wenn ich das Modell erstelle, hat es nicht unbedingt ein verwandtes Modell. Wenn ich es aktualisiere, kann ich eine Option hinzufügen oder nicht.
Ich muss also prüfen, ob das zugehörige Modell existiert, 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, nach dem ich suche.
In php 7.2+ können Sie count
nicht für das Beziehungsobjekt verwenden. Es gibt also keine für alle Beziehungen passende Methode. Verwenden Sie stattdessen die Abfragemethode als @tremby:
$model->relation()->exists()
generische Lösung für alle Beziehungstypen (pre php 7.2):
if (count($model->relation))
{
// exists
}
Dies funktioniert für jede Beziehung, da dynamische Eigenschaften Model
oder Collection
zurückgeben. Beide implementieren ArrayAccess
.
So geht es so:
Einzelbeziehungen: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
_/zu-viele-Beziehungen: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
Ein Relation-Objekt leitet unbekannte Methodenaufrufe an einen Eloquent query Builder weiter, der nur die zugehörigen Objekte auswählen kann. Dieser Builder leitet wiederum unbekannte Methodenaufrufe an its unter Abfrage-Generator weiter.
Das heißt, Sie können die Methoden exists()
oder count()
direkt aus einem Beziehungsobjekt verwenden:
$model->relation()->exists(); // bool: true if there is at least one row
$model->relation()->count(); // int: number of related rows
Beachten Sie die Klammern hinter relation
: ->relation()
ist ein Funktionsaufruf (holt das Beziehungsobjekt), im Gegensatz zu ->relation
, den ein von Laravel für Sie erzeugter magischer Eigenschafts-Getter (das zugehörige Objekt/die zugehörigen Objekte) eingerichtet hat.
Die Verwendung der Methode count
für das Relationsobjekt (d. H. Die Klammern) ist viel schneller als das Ausführen von $model->relation->count()
oder count($model->relation)
(es sei denn, die Relation wurde bereits geladen), da eine Zählabfrage ausgeführt wird, anstatt alle Daten abzurufen alle zugehörigen Objekte aus der Datenbank, um sie nur zu zählen. Ebenso muss mit exists
keine Modelldaten abgerufen werden.
Sowohl exists()
als auch count()
funktionieren für alle Relationstypen, die ich ausprobiert habe, also zumindest belongsTo
, hasOne
, hasMany
und belongsToMany
.
Ich bevorzuge die Methode exists
:
RepairItem::find($id)->option()->exists()
um zu überprüfen, ob ein verwandtes Modell existiert oder nicht. Es funktioniert gut auf Laravel 5.2
Nach Php 7.1 , Die akzeptierte Antwort funktioniert nicht für alle Arten von Beziehungen.
Je nach Typ der Beziehung gibt Eloquent ein Collection
, ein Model
oder Null
zurück. Und in Php 7.1 count(null)
wird eine error
ausgelöst.
Um zu prüfen, ob die Beziehung existiert, können Sie Folgendes verwenden:
Für einzelne Beziehungen: Zum Beispiel hasOne
und belongsTo
if(!is_null($model->relation)) {
....
}
Für mehrere Beziehungen: Zum Beispiel: hasMany
und belongsToMany
if ($model->relation->isNotEmpty()) {
....
}
Ich bin nicht sicher, ob sich dies in Laravel 5 geändert hat, aber die akzeptierte Antwort mit count($data->$relation)
hat für mich nicht funktioniert, da der Zugriff auf die Relationseigenschaft das Laden veranlasst hat.
Am Ende hat eine einfache isset($data->$relation)
den Trick für mich gemacht.
Sie können die Methode relationLoaded für das Modellobjekt verwenden. Das hat meinen Speck gerettet, also hoffentlich hilft es jemand anderem. Ich erhielt diesen Vorschlag gegeben als ich dieselbe Frage an Laracasts stellte.
Wie Hemerson Varela bereits in Php 7.1 gesagt hat, wirft count(null)
eine error
und hasOne
gibt null
zurück, wenn keine Zeile vorhanden ist. Da Sie eine hasOne
relation haben, würde ich die empty
-Methode verwenden, um Folgendes zu überprüfen:
$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();
};
Sie sagten, Sie möchten prüfen, ob die Relation bereits existiert, also können Sie eine update
oder create
ausführen. Dies ist jedoch aufgrund der Methode updateOrCreate nicht erforderlich.
Mach einfach das:
$model = RepairItem::find($id);
$model->option()
->updateOrCreate(['repair_item_id' => $model->id],['option' => 'A']);