2014-02-16 9 views
14

Es tut mir leid zu fragen, aber ich komme aus codeIgniter und habe eine wirklich harte Zeit Verständnis eloquent Modell einfügen. Dies ist eine neue Art, mit Modellen für mich zu arbeiten.laravel: eloquent Beispiel Daten in die Datenbank einfügen

Ich habe gelesen this article und verstehe jetzt einige Grundlagen.

Ich habe folgendes Beispiel. Ich habe ein Produkt, das viele Attribute hat, aber das relevante ist Marken- und Produktname. (Siehe folgende Beispieltabellen)

Produkte: id (PK), Name, Beschreibung, brand_id Marken: id (PK), Name

hier Jetzt kommt das Problem. Ich weiß, dass ich eine neue Marke schaffen kann und ich weiß, wie ich ein neues Produkt schaffen kann. Wie auch immer, ich habe keine Ahnung wie man die beiden miteinander verbindet. Hier ist ein Code, den ich gerade habe. Ich möchte ein neues Produkt erstellen und die Markentabelle automatisch ausfüllen. Dies ist jetzt ein Teil des Controllers.

Kurz gesagt. Ich möchte die Marken.id in den Produkten.brand_id

Um es klarer zu machen. Ich habe 2 Modelle. Produkte und Markenmodelle. Allerdings ist mir nicht klar, was im Modell sein soll. Das ist mein aktuelles Produktmodell. Ich denke, dass das Markenmodell nur einen geschützten $ table = "brands" haben sollte; Linie innerhalb der Modellklasse.

Kann mir jemand erklären, was ich falsch mache. Ich kann keine gute Anleitung finden, wie man Daten in redegewandten Modellen mit Beziehungen einfügt. In den meisten Tutorials werden Daten angezeigt.

+0

Möglicherweise müssen Sie die Marke vor dem Aufruf von $ product-> associate() speichern. – alexrussell

+0

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

Antwort

40

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:

  1. Tabellennamen Plural sind (products, brands)
  2. Fremdschlüssel verwenden die Singular (brand_id)
  3. Modellnamen sind singulär und StudlyCase (so Product für einen Tisch products, Brand für Tabelle brands)
  4. Die Eigenschaft $table muss nicht angegeben werden, solange Sie den Laravel-Konventionen folgen (dh Tabellenname ist die Plural-snake_case-Version des Modells Klassenname
  5. sollten Sie die Beziehung definieren beide Wege
  6. 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)
  7. 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 $brandid 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.

+1

Nicht sicher, wer das abgelehnt hat, aber wie kommt es? Ich dachte, meine Antwort sei ziemlich gut durchdacht und beantworte die Frage ebenso wie Verbesserungen des ursprünglichen Codes (da es ein wenig unordentlich war und möglicherweise nicht so funktioniert hat, wie es war). Sehr glücklich Kritik zu hören. – alexrussell

+0

Das ist genau die Antwort, nach der ich gesucht habe. Es hat funktioniert und auch wichtig: Ich habe ein klares Beispiel für die Namenskonvention bekommen. Thnx – Klaas

+0

Kein Problem. Frei frei zu upvote auch, um die Arbeit von wer rückgängig gemacht es rückgängig machen, wenn Sie wollen. – alexrussell

Verwandte Themen