Laravel与复合非标准外键的关系

时间:2016-07-11 02:51:56

标签: laravel

我很遗憾地需要从第三方供应商导入数据,并在我的laravel项目中使用他们的非标准数据库模式。另外,我需要存储多个"公司,"每个人都有自己的数据库用户。

我试图找出使用Eloquent处理这些表之间关系的最佳方法(如果可以的话)。例如,我的表结构如下:

 BmPerson
  'id',
  'firmId',
  'personId'

BmCoverage
  'id',
  'firmId',
  'personId',
  'securityId'

BmSecurity
  'id',
  'firmId',
  'securityId'

...例如,我需要关联一个" BmPerson"与许多" BmSecurity"通过" BmCoverage"表。

但我需要以某种方式使用复合键,因为我正在存储多个"公司"在每个表中(根据第三方供应商的数据库模式)。

我到目前为止使用的一种方法是确定范围,例如:对于我的BmCoverage模型:

 public function scopeFromFirm($query,$firmId){
  return $query->where('firmId','=',$firmId);//->where('personId','=',$personId);}

public function scopeFromPerson($query,$personId){
  return $query->where('personId','=',$personId);//->where('personId','=',$personId);}

然后我可以检索个人的覆盖列表,但我仍然需要以某种方式关联" BmCoverage"与BmSecurities。" BmSecurities。"我想我也可以在BmSecurities类中添加一个范围,但是使用Eloquent会更好。

有没有人提出在laravel模型关系中使用复合键的好方法,还是我应该坚持使用范围方法?

4 个答案:

答案 0 :(得分:2)

您需要的所有内容都可以在https://laravel.com/docs/5.2/eloquent-relationships

找到

您可以轻松定义哪些cols sohuld是引用的键。

示例:

public function bmCoverages() {
    return $this->hasMany('App\BmCoverage', 'firmId', 'id');
}

这可能属于您的App \ Firm或其他任何名称。

通常,hasMany关系看起来像这样

return $this->hasMany('App\Comment', 'foreign_key', 'local_key');

如您所见,您可以指定密钥。

答案 1 :(得分:0)

阅读laravel hasManyThrough关系。它将帮助您更轻松地编写此查询

https://laravel.com/docs/5.1/eloquent-relationships#has-many-through

答案 2 :(得分:0)

正如其他人所说,您需要使用HasManyHasManyThrough关系。

根据您的表定义,您只需访问:

  • Person->BmCoverage(s)
  • Person->BmSecurity(s)个人。

我认为这里的主要问题是将BmSecurity与BmCoverage联系起来,显然每coverage_id没有BmSecurity,而是通过firmId和{{}进行复合映射{1}}。

在这种情况下,不幸的是,Laravel并没有正式支持复合键,尽管你可以使用trait like this ...但你也可以通过一些棘手的hasMany来实现它。

即。关于BmCoverage

securityId

同样适用于使用$this->hasMany('BmSecurity', 'securityId', 'securityId') ->andWhere('firmId', '=', $this->firmId); 的BmPerson的BmSecurity。

希望有所帮助。

答案 3 :(得分:0)

有一个here软件包似乎很适合您的情况:

  

Compoships提供了基于两个指定关系的功能   Laravel 5的Eloquent中的(或更多)列。需要匹配多个   雄辩关系的定义中经常出现列   与第三方或现有的架构/数据库一起使用时。

您将像这样使用它:

class BmPerson extends Model
{
    use \Awobaz\Compoships\Compoships;

    public function bmCoverages()
    {
        return $this->hasMany('App\BmCoverage', ['firmId', 'personId'], ['firmId', 'personId']);
    }
}

如果每个BmSecurity恰好属于一个BmCoverage,并且每个BmCoverage恰好属于一个BmPerson,则可能更容易用{{1 }}在'firmId', 'personId'数据库中; bmperson_id中的BmCoverage'firmId', 'securityId'。然后,您可以使用默认的bmcoverage_id关系和一个键。