我已经读过this article,现在了解一些基础知识.
我有以下例子.我有一个产品有很多属性,但相关的是品牌和产品名称. (见下面的示例表)
产品:id(PK),name,description,brand_id
品牌:id(PK),名称
现在这里有问题.我知道我可以创建一个新的品牌,我知道如何创建一个新的产品.但是,我没有任何连接两个人的气味.这是我现在的一些代码.我想创建一个新产品并自动填写品牌表.这是控制器的一部分.
简而言之.我想要brand.id里面的products.brand_id
$product = new Products; $product->name = "product1"; $product->description = "description1"; $brand = new Brands; $brand->name = "brand1" $product->brand()->associate($brand); $brand->save(); $product->save();
使其更加清晰.我有两个型号.产品和品牌型号.但是,我不清楚在模型中应该是什么.这是我当前的产品型号.我认为品牌型号只应该有一个受保护的$table =“品牌”;线内模型类.
class Products extends Eloquent { protected $table = 'products'; public function brand() { return $this->hasOne('brands'); } }
有人可以向我解释我做错了什么我找不到一个很好的教程如何使用在有雄辩的模型与关系插入数据.最多的教程是关于显示数据.
解决方法
首先,你的关系是错误的类型和错误的方式.据我了解(并且在我自己的工作中实施这些事情)产品属于一个品牌 – 一个品牌可能有多个产品,但一个产品只能有一个品牌.所以首先你的DB模式 – 你提到你有一个产品表与正常的列,然后是外键brand_id.到目前为止这么好:这与我解释关系的方式是一致的.
然而,您随后继续向我们展示您的模型.您的产品型号为“有品牌” – 但实际上它属于品牌.你也没有定义关系的倒数 – 你需要双方使Laravel运行良好.除此之外,您的命名有点不合适 – 它可能会起作用,但如果我们遵循Laravel约定,我们得到以下内容:
在产品型号:Product.PHP
class Product extends Eloquent { public function brand() { return $this->belongsTo('Brand'); } }
现在品牌型号:Brand.PHP
class Brand extends Eloquent { public function products() { return $this->hasMany('Product'); } }
好的,到目前为止这么好.你会注意到各种惯例:
>表名是复数(产品,品牌)
>外键使用单数(brand_id)
>型号名称是单数和StudlyCase(所以产品为表产品,品牌为表品牌)
>只要遵循Laravel约定,就不必指定$table属性(即表名称是模型类名的复数snake_case版本
>你应该以两种方式定义关系(每个模型中都有一个,belongsTo的inverse有很多,还有对hasOne / belongsTo和belongsToMany / belongsToMany)
>检索关系的方法的名称是明智的 – 如果你期望一个结果,使它是单一的(品牌在产品),如果你期望多个结果复数(品牌中的产品)
>使用关系定义中的模型类名($this-> hasMany(‘Brand’)不是$this-> hasMany(‘brands’)或任何其他变体
如果您遵守这些规则,您的模型可以非常简洁但非常强大.
现在,至于你如何真正定义真实的数据,我感觉你发布的代码可能会正常工作(这真的取决于Laravel是如何聪明的),但正如我在第一个评论中所建议的那样,我会确保我在调用associate()之前保存了这个$品牌,这样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(),因为它将自动获取$品牌的id值,将其放入$product的brand_id字段中,然后保存$product.
有关更多信息,请参阅如何执行此关系的文档插入:http://laravel.com/docs/eloquent#one-to-many
无论如何,希望这个帖子清除了很多你的代码出了什么问题.如上所述,这些是公约,你可以反对它们,但是要做到这一点,你必须开始添加额外的代码,对于其他开发人员来说,这可能是不可读的.我说如果你选择一个给定的框架,你可以遵循它的惯例.