Laravel 特殊关联关系问题

首先需求如下:

A表中有三个字段关联到B表,分别是a_id,b_id,c_id;B表中通过type确定不同的字段关联,比如type='a'的时候关A表的a_id,type='b'的时候关联到b_id。
Laravel特殊关联关系问题
关联部分代码:
Laravel特殊关联关系问题

现在遇到问题如下:

如果通过$this->type去动态的选择关联关系,会导致with或者whereHas中报错,只能在实例化A的情况下才能够正常使用,希望有做过类似需求的给点建议。已经尝试过多态关联,和目前需求有点不符。

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

很久过去了,自己现在来对这个问题做下总结,避免这个问题成为没有答案的问题。

首先总结一下我自己找到的答案包括上面大家提到的答案:

  • 修改表结构,因为确实这个表结构有点问题,设计的不是很合理,甚至说不应该出现子表关联父表这种操作
  • 使用原生sql,使用原生sql去实现query生成,这个对于一些新手,或者在一些比较大的项目中并不是很稳妥
  • 写三个关联,商品确实可以找到三种不同的图片,图片要找商品的时候代码相对会比较奇怪,要自己合并三个关联关系,才能实现反向关联,使得图片可以关联到对应的商品
  • 多态,这个是我觉得比较合适的方法,算是不得已的办法中的办法,大家可以自己看下文档 多态关联文档
4年前 评论
讨论数量: 12

@Kamicloud 感谢回答,官方的多态关联与我的需求似乎不符,我有尝试过

4年前 评论
半人间 4年前
皮皮强 (作者) (楼主) 4年前

@ycq3 抱歉,没看仔细,我的也不支持这种。

如果需要从父关联子,我建议你加多个关联关系。子关联到父虽然也可以用多个关联,但是有点麻烦。

4年前 评论

一个关联关系在你预加载时,会默认用第一个命中到,所以这样不行的。
除非场景中只有n+1的方式一个一个从数据库读

4年前 评论

看了你的说明。提出一点自己看法

在A表中分别有,a_id,b_id,c_id分别指向B表的ID。
我的问题是,在B表中,id是不重复的,那么在关联时,是不是B表中的type(a,b,c),可以不考虑,直接做一对一关联即可

public function headImg() {
        return $this->belongsTo('ProductModel', 'a_id', 'id');
 }
 public function iconImg() {
        return $this->belongsTo('ProductModel', 'b_id', 'id');
 }
 public function detailsImg() {
        return $this->belongsTo('ProductModel', 'c_id', 'id');
 }

如果,对应的图不存在时,即可为0

4年前 评论

@yangchangdong 首先表示感谢,你的意思我知道,但是这样就不能提供统一方法了,如果我需要得到Product需要通过headImgheadImgheadImg三个方法来处理,同样的在使用with或者whereHas的时候就会造成一些麻烦。

4年前 评论

看了你的图,如果是商品表与图片表的关联问题我的设计思路是不同的。
从你的列子上看 A_id和C_id对应图的数量应该是一个复数。商品头图是多张且可左右划动。那么你的这种设计方式就无法实现了。

A表是商品表
B表是图片表 字段 id,product_id,type(a,b,c),...

class AModel extends Eloquent {
  protected $table = 'a';
  public function hasImg()
  {
    return $this->hasMany('b', 'product_id', 'id');
  }
}

调用方法:

$products = AModel::with('hasImg')->get();

从得到的结果中的type区分图片类型
在prducts列表中的 has_img下的数组中的type来区分具体的图片类型

4年前 评论

把外键放在图片表会不会容易写呢,假如一个商品有多张详情图,或者多张主图。


# product.php
public function cover()
{
    return $this->hasOne/hasMany(Image::class, 'product_id')->where('type', 'cover')
}
4年前 评论

@yangchangdong 感谢回复,可能我前面没有阐述清楚,A必定有a_idb_id,c_id关联三种图片,且为一对一关联。希望最好时不要动到表结构能够解决关联问题,如果有更好的建议我也可以尝试一下,但是要改表结构比较麻烦。

4年前 评论

@Max 感谢,最近收到不少建议都是说考虑修改一下表结构,如果单前做法实现确实过于麻烦,我想办法转一下表结构

4年前 评论

关注此问题一下

4年前 评论

如果不用orm的话是不是很好解决呢

4年前 评论

很久过去了,自己现在来对这个问题做下总结,避免这个问题成为没有答案的问题。

首先总结一下我自己找到的答案包括上面大家提到的答案:

  • 修改表结构,因为确实这个表结构有点问题,设计的不是很合理,甚至说不应该出现子表关联父表这种操作
  • 使用原生sql,使用原生sql去实现query生成,这个对于一些新手,或者在一些比较大的项目中并不是很稳妥
  • 写三个关联,商品确实可以找到三种不同的图片,图片要找商品的时候代码相对会比较奇怪,要自己合并三个关联关系,才能实现反向关联,使得图片可以关联到对应的商品
  • 多态,这个是我觉得比较合适的方法,算是不得已的办法中的办法,大家可以自己看下文档 多态关联文档
4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!