2014-02-16 129 views
14

我很抱歉問這個問題,但我來自codeIgniter,並且很難理解雄辯的模型插入。這是一種與我合作的新模式。laravel:雄辯的例子插入數據到數據庫

我已閱讀this article並瞭解一些基本知識。

我有下面的例子。我有一個產品有很多屬性,但相關的是品牌和產品名稱。 (請看下面的例子表)

產品:ID(PK),名稱,描述,brand_id 品牌:ID(PK),名

現在,這裏是問題。我知道我可以創建一個新品牌,並且我知道如何創建一個新產品。但我不知道如何將兩者連接在一起。這裏是我現在的一些代碼。我想創建一個新產品並自動填充品牌表。這是現在控制器的一部分。

總之。我想要products.id內的品牌.id

$product = new Products; 
    $product->name = "product1"; 
    $product->description = "description1"; 

    $brand = new Brands; 
    $brand->name = "brand1" 
    $product->brand()->associate($brand); 

    $brand->save(); 
    $product->save(); 

爲了更清楚。我有2個模型。產品和品牌模型。但是,我不清楚模型中應該包含什麼。這是我現有的產品型號。我認爲品牌模型只應該有一個受保護的$ table =「品牌」;在模型類裏面。

class Products extends Eloquent { 

    protected $table = 'products'; 

    public function brand() 
    { 
     return $this->hasOne('brands'); 
    } 
    } 

有人可以向我解釋我做錯了什麼。我無法找到一個很好的教程,如何在有關係的雄辯模型中插入數據。大多數教程都是關於顯示數據的。

+0

甚至在調用'$ product-> associate();之前,您可能需要保存品牌。 – alexrussell

+0

剛剛在你的文章中發現,你認爲你「認爲品牌模型只應該有一個'保護$ table =」品牌「;'線條」,但據我所知這不是真的。我很確定這個模型必須有一個'public function product(){return $ this-> belongsTo('Product'); }'方法,那麼$ products模型上的'associate()'調用可以填充'Brands'模型中的'product_id'字段。我不是100%擁有'hasOne',但這絕對是如何與'hasMany'搭配的,並且它與關係相反(即模型具有'foreign_id'列)是同一類事物。 – alexrussell

回答

40

好的,我已經重新閱讀了你的問題,我認爲你有一些錯誤,所以不要在主要帖子上留下任何進一步的評論,我想我可以在答案中留下一個答案,所以在這裏。

首先,你的關係是錯誤的類型和錯誤的方式。據我瞭解(並且在我自己的工作中實施這些事情),產品屬於一個品牌 - 一個品牌可能有多個產品,但一個產品只能有一個品牌。所以首先你的數據庫模式 - 你提到你有一個products表與正常的列,然後外鍵brand_id。到目前爲止,這很好:這與我解釋關係的方式一致。

然而,你然後繼續向我們展示你的模型。您的產品型號爲hasOne品牌 - 但實際上它屬於一個品牌。你也沒有定義關係的逆向 - 你需要雙方都使Laravel運作良好。此外,你的命名是有點不正常了 - 它可能會工作,但如果我們按照Laravel約定,我們得到如下:

products模式:Product.php

class Product extends Eloquent 
{ 
    public function brand() 
    { 
     return $this->belongsTo('Brand'); 
    } 
} 

現在brands型號:Brand.php

class Brand extends Eloquent 
{ 
    public function products() 
    { 
     return $this->hasMany('Product'); 
    } 
} 

好吧,迄今爲止好。你會發現各種公約:

  1. 表名是複數(productsbrands
  2. 外鍵使用單數(brand_id
  3. 型號名稱是單數和StudlyCase(所以Product爲表productsBrandbrands
  4. $table屬性不必指定,只要你按照Laravel的約定(即表名是模型類名的複數snake_case版本
  5. 你應該定義的關係是雙向的(每個模型,belongsTo的倒數爲hasMany,另外還有對hasOne/belongsTobelongsToMany/belongsToMany
  6. 的方法的名稱檢索關係是明智的 - 如果你期待一個結果,使之奇(在Productbrand),如果你期望多個結果使複數(productsBrand
  7. 使用在你的關係定義模型類名($this->hasMany('Brand')沒有$this->hasMany('brands')或任何其它變化

如果你堅持這些規則,你的模型可以非常簡潔但非常強大。

現在,至於你如何真正定義實際數據,我感覺你發佈的代碼可能工作得很好(這實際上取決於Laravel在幕後的聰明程度),但正如我在第一條評論中所建議的,我'd確保我在致電associate()之前保存了$brand,這樣Laravel就不會迷路了。因此我會去:

// 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(); 

這樣,你知道你的品牌與它的ID數據庫你去有關係使用它之前已經定義。

您還可以定義以相反的方式的關係,它可能不太腦傷害這樣做:

// 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); 

你不需要最後一行後打電話到save()在任模型,因爲它會自動取$brandid值,將其放入$productbrand_id字段,然後保存$product

欲瞭解更多信息,請參閱如何做到這一點的關係插入文檔:http://laravel.com/docs/eloquent#one-to-many

無論如何,希望這篇文章澄清了什麼是錯的代碼量好。正如我上面所說的,這些都是慣例,你可以反對它們,但是爲了做到這一點,你必須開始添加額外的代碼,而其他開發者可能無法讀取它。我說如果你選擇一個給定的框架,你可以遵循它的約定。

+1

不知道誰低估了這個,但是怎麼來的?我認爲我的回答非常深思熟慮,並回答了問題,並建議對原始代碼進行改進(因爲它有點混亂,甚至可能沒有按原樣工作)。非常高興聽到批評。 – alexrussell

+0

這正是我尋找的答案。它的工作也很重要:我明確了一個命名約定的例子。 Thnx – Klaas

+0

完全沒問題。如果您願意,也可以免費上傳以解除任何人的努力。 – alexrussell