Okay, ich habe Ihre Frage noch einmal gelesen und ich denke, Sie haben ein paar Dinge falsch, so dass ich keine weiteren Kommentare auf dem Hauptpost hinterlassen würde, dachte ich, ich könnte eine Antwort geben, also hier geht.
Zunächst ist Ihre Beziehung der falsche Typ und der falsche Weg herum. Wie ich es verstehe (und diese Dinge in meiner eigenen Arbeit umsetzen), gehört ein Produkt zu einer Marke - eine Marke kann mehrere Produkte haben, aber ein Produkt kann nur eine Marke haben. Also zuerst Ihr DB-Schema - Sie erwähnen, Sie haben eine products
Tabelle mit den normalen Spalten und dann den Fremdschlüssel brand_id
. So weit, so gut: Das entspricht der Art, wie ich die Beziehung interpretiere.
Sie zeigen uns dann aber Ihr Modell. Sie haben das Produktmodell als hasOne
Brand - aber eigentlich gehört es zu einer Marke. Sie definieren auch nicht die Umkehrung der Beziehung - Sie brauchen beide Seiten, damit Laravel gut funktioniert.Zusätzlich zu, dass Ihre Namensgebung ist ein bisschen aus dem Gleichgewicht geraten - es wird möglicherweise funktionieren, aber wenn wir Laravel Konventionen folgen erhalten wir folgendes:
Im products
Modell: Product.php
class Product extends Eloquent
{
public function brand()
{
return $this->belongsTo('Brand');
}
}
Nun ist die brands
Modell: Brand.php
class Brand extends Eloquent
{
public function products()
{
return $this->hasMany('Product');
}
}
Okay so weit so gut. Sie werden verschiedene Konventionen bemerken:
- Tabellennamen Plural sind (
products
, brands
)
- Fremdschlüssel verwenden die Singular (
brand_id
)
- Modellnamen sind singulär und StudlyCase (so
Product
für einen Tisch products
, Brand
für Tabelle brands
)
- Die Eigenschaft
$table
muss nicht angegeben werden, solange Sie den Laravel-Konventionen folgen (dh Tabellenname ist die Plural-snake_case-Version des Modells Klassenname
- sollten Sie die Beziehung definieren beide Wege
- Die Namen der Verfahren (eine in jedem Modell,
belongsTo
‚s inverse ist hasMany
gibt auch hasOne
/belongsTo
und belongsToMany
/belongsToMany
die Paare ist), um die Beziehung sinnvoll sind abzurufen - wenn Sie ein Ergebnis erwarten, machen es Singular (brand
in Product
), wenn Sie mehrere Ergebnisse erwarten, dass es mehrere machen (products
in Brand
)
- Verwenden Sie die Modell-Klassennamen in Ihrer Beziehung Definitionen (
$this->hasMany('Brand')
nicht $this->hasMany('brands')
oder jede andere Variation
Wenn Sie sich an diese Regeln halten, können Ihre Modelle sehr präzise, aber sehr leistungsfähig sein.
Nun, wie Sie tatsächlich echte Daten definieren, habe ich das Gefühl, dass der Code, den Sie geschrieben haben, gut funktionieren kann (es hängt wirklich davon ab, wie clever Laravel hinter den Kulissen ist), aber wie ich in meinem ersten Kommentar vorgeschlagen habe 'd sicherstellen, dass ich die $brand
vor dem Aufruf associate()
gespeichert, nur damit Laravel nicht verloren geht, herauszufinden, was zu tun ist. Als solche würde ich gehen für:
// create new brand and save it
$brand = new Brand;
$brand->name = "Brand 1";
$brand->save();
// create new product and save it
$product = new Product;
$product->name = "Product 1";
$product->description = "Description 1";
$product->brand()->associate($brand);
$product->save();
diese Weise werden Sie wissen, dass Sie die Marke in der Datenbank mit den IDs bereits definiert, bevor Sie gehen und es in einer Beziehung verwenden.
Sie können auch die Beziehung in entgegengesetzter Weise definieren, und es kann weniger, dies zu tun seines Gehirn zu verletzen:
// create new product and save it
$product = new Product;
$product->name = "Product 1";
$product->description = "Description 1";
$product->save();
// create new brand and save it
$brand = new Brand;
$brand->name = "Brand 1";
$brand->save();
// now add the product to the brand's list of products it owns
$brand->products()->save($product);
Sie brauchen nicht save()
nach der letzten Zeile auf beiden Modelle zu nennen, Da der Wert $brand
id
automatisch übernommen wird, platzieren Sie ihn in das Feld brand_id
, und speichern Sie dann die $product
.
Weitere Informationen finden Sie die Dokumentation, wie diese Beziehung Einfügen tun: http://laravel.com/docs/eloquent#one-to-many
Wie auch immer, hoffentlich löscht diesen Beitrag eine gute Menge, was mit Ihrem Code falsch war. Wie ich oben sagte, sind dies Konventionen, und Sie können gegen sie gehen, aber dazu müssen Sie beginnen, zusätzlichen Code einzufügen, und es kann für andere Entwickler ziemlich unlesbar sein. Ich sage, wenn Sie einen gegebenen Rahmen wählen, können Sie auch seinen Konventionen folgen.
Möglicherweise müssen Sie die Marke vor dem Aufruf von $ product-> associate() speichern. – alexrussell
Gerade bemerkt in Ihrem Beitrag Sie sagen, dass Sie "denken, dass das Markenmodell nur ein' geschütztes $ table = "Marken" haben sollte; "Linie", aber das stimmt nicht so weit ich weiß. Ich bin mir ziemlich sicher, dass das Modell ein öffentliches Funktionsprodukt haben muss() {return $ this-> objectsTo ('Product'); } 'Methode, auf diese Weise kann der Aufruf von' associate() 'auf dem $ products-Modell das' product_id'-Feld im 'Brands'-Modell ausfüllen. Ich bin nicht 100% mit einem 'hasOne', aber das ist definitiv wie es ist mit einem' hasMany', und es ist die gleiche Sache in der Umkehrung der Beziehung (d. H. Das Modell hat eine 'fremid_id'-Spalte). – alexrussell