【问题标题】:How to best implement one to many relationship Laravel如何最好地实现一对多关系 Laravel
【发布时间】:2020-09-23 14:37:11
【问题描述】:

我正在使用 Laravel 开发后端。我想保存一个模型,假设它是我的数据库中的衬衫。一件衬衫可以有许多不同的尺寸,所以我希望能够将这样的衬衫记录保存到我的数据库中:

{
   "name": "A good shirt",
   "descripton": "this shirt is very good",
   "price": "$100",
   "sizes": ["XL","L","M","S"]  <--------- what I want
}  

我的问题是,我怎样才能在我的后端保存实现这个?如何将不同尺寸的数组保存到我的模型中,并确保保存此记录时,它符合可用的衬衫尺寸之一?例如,我想确保一件衬衫只能有从小到大的尺寸。

我考虑创建一个名为 Shirt_Sizes 的新模型,并让记录成为可用的衬衫尺寸,然后在我的 Shirt Model 中设置一个外键。但是我很难弄清楚如何将许多衬衫尺寸保存到 Shirt 模型中。

我愿意接受除此之外的其他建议。

谢谢!

【问题讨论】:

    标签: php laravel eloquent foreign-keys backend


    【解决方案1】:

    您的场景是多对多关系,即一件衬衫可以有多种尺码,一种尺码可以有多种衬衫,因此我建议按照 Laravel 文档的规定创建两个表格。https://laravel.com/docs/7.x/eloquent-relationships#many-to-many

    shirt
        id - integer
        name - string
        description - string
        price - integer
    
    sizes
        id - integer
        name - string
    
    sizes_shirts
        shirt_id - integer
        size_id - integer

    您的模型如下所示:

    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Shirt extends Model
    {
        /**
         * The sizes that belong to the shirt.
         */
        public function sizes()
        {
            return $this->belongsToMany('App\Size');
        }
    }

    如何保存衬衫的尺码:

    $sizes_ids = [1, 2, 3];
    $shirt->sizes()->sync($sizes_ids);
    

    如何获得衬衫的尺码:

    $sizes_of_shirt = $shirt->sizes;
    

    【讨论】:

      【解决方案2】:

      如果一件衬衫有很多尺码并且这些尺码可以属于很多衬衫,那么您必须定义一个多对多关系,您可以为衬衫尺码制作一个单独的表格sizes,然后创建一个第二个表 shirt_size 包含 shirt_idsize_id 将它们与外键链接到您的 shirtssizes 表。

      然后您将定义两个模型之间的适当关系

      尺寸模型

      class Size extends Model
         {
         // Get the shirts for this size.
         public function shirts()
         {
             return $this->belongsToMany(Shirt::class, 'shirt_size', 'size_id', 'shirt_id');
         }
      } 
      

      衬衫模特

      class Shirt extends Model
      {
         // Get the size for the shirt.
         public function sizes()
         {
              return $this->belongsToMany(Size::class, 'shirt_size', 'shirt_id', 'size_id');
         }
      }
      

      那么当您需要存储一件新衬衫的尺寸时,这取决于您发送的请求:

      1. 发送大小数组ids:

        然后您需要使用validate 验证ID:

       $validatedData = $request->validate([
           'sizes.*.size_id' => 'required|integer|exists:sizes,id',
       ]);
      
      1. 发送大小数组names:

        然后您需要使用validate 验证名称:

       $validatedData = $request->validate([
           'sizes.*.size_name' => 'required|string|exists:sizes,name',
       ]);
      

      然后在创建衬衫记录后,您可以使用attach() 方法为衬衫保存多个尺寸:

      foreach ($validatedData['sizes'] as $size){
         $shirt->sizes()->attach($size['size_id']);
      }
      

      或者

      foreach ($validatedData['sizes'] as $size){
         $size_id  = Size::where('size_name',$size['name'])->get('id'));
         $shirt->sizes()->attach($size_id);
      }
      

      【讨论】:

      • 惊人的答案非常感谢!你能再给我提供一条信息吗?在请求所有衬衫时,我希望将衬衫尺寸作为数组包含在请求中。我曾想过用衬衫上的“受保护”来做到这一点。这是实现这一点的最佳和最简单的方法吗?
      • 是的,在你的 shirt 模型中定义 protected $with = ['sizes']; 应该加载你想要的。
      • 如果我以后需要更新尺寸并拿走一个尺寸,例如
      • 您可以使用detach($size_id) 删除衬衫的尺寸。
      猜你喜欢
      • 2015-02-06
      • 1970-01-01
      • 2016-10-12
      • 2019-02-02
      • 1970-01-01
      • 1970-01-01
      • 2012-06-22
      • 1970-01-01
      • 2013-08-08
      相关资源
      最近更新 更多