【问题标题】:How to join models in Laravel 5?如何在 Laravel 5 中加入模型?
【发布时间】:2015-06-16 05:20:05
【问题描述】:

我有三个表,具有这样的结构(它们在 MySQL 数据库中)连接到我的 Laravel 5 API 和 Eloquent 模型:

# build_sets table
| id | title | description |

# parts table
| id | title | description | color |

# build_set_parts table
| id | build_set_id | part_id | amount | special_info |

目前我做这样的查询:

$buildSets = array();

foreach(BuildSet::with('parts')->get() as $buildSet) {
    $temp = json_decode($buildSet);

    $temp->parts = $buildSet->parts;

    $buildSets[] = $temp;
}

return $buildSets;

我的模型看起来像这样:

class BuildSet extends Model
{
    protected $table = 'build_sets';
    protected $hidden = ['created_at', 'updated_at'];

    public function parts()
    {
        return $this->hasMany('App\Models\BuildSetPart');
    }
}

class Part extends Model
{
    protected $table = 'parts';
    protected $hidden = ['id', 'created_at', 'updated_at'];

    public function buildSets()
    {
        return $this->hasMany('App\Models\BuildSet');
    }
}

class BuildSetPart extends Model
{
    protected $table = 'build_set_parts';
    protected $hidden = ['id', 'build_set_id', 'part_id', 'created_at', 'updated_at'];

    public function buildSet()
    {
        return $this->belongsTo('App\Models\BuildSet');
    }

    public function part()
    {
        return $this->belongsTo('App\Models\Part');
    }
}

我得到这样的结果(JSON 响应):

[
  {
    "id": 1,
    "title": "Build set 1",
    "description": "This is a small build set.",
    "parts": [
      {
        "amount": 150,
        "special_info": ""
      },
      {
        "amount": 400,
        "special_info": "Extra strong"
      },
      {
        "amount": 25,
        "special_info": ""
      }
    ]
  },
  {
    "id": 2,
    "title": "Build set 2",
    "description": "This is a medium build set.",
    "parts": [
      {
        "amount": 150,
        "special_info": ""
      },
      {
        "amount": 400,
        "special_info": "Extra strong"
      },
      {
        "amount": 25,
        "special_info": ""
      },
      {
        "amount": 25,
        "special_info": ""
      },
      {
        "amount": 25,
        "special_info": ""
      }
    ]
  }
]

如您所见,构建集中包含的“部件”数组中缺少标题、描述和颜色。 所以我的问题是,如何在我的回复中添加标题和颜色?我可以通过使用 Eloquent 模型来做到这一点,还是我必须进行自己的数据库查询,在其中获取所有构建集,然后迭代它们并获取所有部件并构建集部件,然后合并该结果并将其添加到构建集.

任何人都有一个很好的解决方案,它将给我部件数组中的项目,格式如下:

[
  {
    "title": "Part 1",
    "color": "Red",
    "amount": 25,
    "special_info": ""
  },
  {
    "title": "Part 2",
    "color": "Green",
    "amount": 75,
    "special_info": ""
  }
]

【问题讨论】:

    标签: php mysql laravel eloquent laravel-5


    【解决方案1】:

    根据您的模型,您在 BuildSetPart 之间建立了多对多关系。

    因此,在BuildSet 中,可以使用hasManyThrough 关系。

    型号BuildSet

    public function parts()
    {
        return $this->hasManyThrough('App\Models\Part', 'App\Models\BuildSetPart');
    }
    

    来源:http://laravel.com/docs/5.0/eloquent#relationships

    无论如何,如果你想保持BuildSetBuildSetPart之间的关系。

    我建议你改用这个。

    public function buildSetPart()
    {
       return $this->hasMany('App\Models\BuildSetPart');
    }
    

    注意:现在,您在 BuildSet 模型中同时获得了 parts()buildSetPart()

    创建关系后,你可以替换你的代码

    $buildSets = array();
    
    foreach(BuildSet::with('parts')->get() as $buildSet) {
        $temp = json_decode($buildSet);
    
        $temp->parts = $buildSet->parts;
    
        $buildSets[] = $temp;
    }
    
    return $buildSets;
    

    return  BuildSet::with('parts')->get();
    

    或者,如果您想要 JSON 格式的输出

    return  BuildSet::with('parts')->toJson();
    

    来源:http://laravel.com/docs/5.0/eloquent#collections

    【讨论】:

    • 感觉好像有误会,我似乎无法通过我的数据透视表(build_set_parts)连接并从该表中获取额外信息以及来自链接的表(部分)中的信息到数据透视表。
    • 我使用了您的一些想法,但必须使用“->withPivot()”函数才能使其正常工作,请参阅我的答案以获取信息。
    【解决方案2】:

    我找到了一个几乎如我所愿的解决方案,我尝试了 mininoz 解决方案,发现我在数据透视表关系方面遇到了一些问题。

    我现在做这个查询:

    return BuildSet::with('parts')->get();
    

    我的模型现在看起来像这样,注意我最后添加的“->withPivot()”函数,它允许我“访问”数据透视表中的列:

    class BuildSet extends Model
    {
        protected $table = 'build_sets';
        protected $hidden = ['created_at', 'updated_at'];
    
        public function parts()
        {
            return $this->belongsToMany('App\Models\BuildSetPart', 'build_set_parts')->withPivot('amount', 'special_info');
        }
    }
    
    class Part extends Model
    {
        protected $table = 'parts';
        protected $hidden = ['id', 'created_at', 'updated_at'];
    
        public function buildSets()
        {
            return $this->belongsToMany('App\Models\BuildSet', 'build_set_parts')->withPivot('amount', 'special_info');
        }
    }
    
    class BuildSetPart extends Model
    {
        protected $table = 'build_set_parts';
        protected $hidden = ['id', 'build_set_id', 'part_id', 'created_at', 'updated_at'];
    }
    

    我现在在我的构建集响应中得到一个扩展的部件响应(注意,我在这里只显示部件数据,构建集数据和以前一样带有“部件”数组):

    [
      {
        "title": "Part 1",
        "color": "Red",
        "pivot": {
          "build_set_id": 1,
          "part_id": 1,
          "amount": 25,
          "special_info": ""
        }
      },
      {
        "title": "Part 2",
        "color": "Green",
        "pivot": {
          "build_set_id": 1,
          "part_id": 2,
          "amount": 55,
          "special_info": ""
        }
      }
    ]
    

    此响应包含我需要的所有内容,但如果我想在 JSON 响应层次结构中的同一“级别”上获取所有内容,我需要进行转换。

    【讨论】:

      猜你喜欢
      • 2016-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-19
      • 1970-01-01
      • 2015-08-08
      • 2015-12-14
      相关资源
      最近更新 更多