具有复合非标准外键的Laravel关系

qlvxas9a  于 2023-03-09  发布在  其他
关注(0)|答案(5)|浏览(188)

不幸的是,我需要从第三方供应商那里导入数据,并在我的laravel项目中使用他们的非标准数据库模式,此外,我需要存储多个“公司”,每个公司在我的数据库中有自己的用户集。
我试图找出使用Eloquent处理这些表之间关系的最佳方法(如果可以做到的话),例如,我的表结构如下:

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

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

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

...例如,我需要通过“BmCoverage”表将一个“BmPerson”与多个“BmSecurity”关联起来。
但是我需要使用组合键,因为我在每个表中存储了多个“公司”(根据第三方供应商的数据库模式)。
到目前为止,我使用过的一种方法是确定范围,例如:对于我的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类的作用域,但最好只使用Eloquent。
有没有人提出了一个在laravel模型关系中使用组合键的好方法,或者我应该坚持使用scoping方法?

4xrmg8kj

4xrmg8kj1#

有一个软件包here似乎非常适合您的情况:
Compoships提供了基于Laravel 5的Eloquent中的两个(或更多)列指定关系的能力。在使用第三方或预先存在的模式/数据库时,经常需要在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,则在BmCoverage DB中用bmperson_id替换'firmId', 'personId'可能更容易;以及'firmId', 'securityId'BmSecurity中的bmcoverage_id的关系。然后,您可以使用具有一个键的默认hasMany关系。

4ngedf3f

4ngedf3f2#

您所需的一切都可以在https://laravel.com/docs/5.2/eloquent-relationships中找到
您可以很容易地定义哪些列是引用的键。
示例:

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

这可能属于您的App\Firm或其他名称。
一般情况下,hasMany关系如下所示

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

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

btqmn9zl

btqmn9zl3#

正如其他人所说,您需要使用HasManyHasManyThrough关系。
在表定义中,您只需访问:

  • Person->BmCoverage(s)
  • Person->BmSecurity(s)的个体。

我认为这里的主要问题是将BmSecurity与BmCoverage联系起来,因为显然没有coverage_id/BmSecurity,而是通过firmIdsecurityId的复合Map。
不幸的是,在这种情况下,Laravel并不正式支持组合键,虽然您可以使用trait like this...但是您也可以使用一些棘手的hasMany实现相同的效果。
即BmCoverage

$this->hasMany('BmSecurity', 'securityId', 'securityId')
     ->andWhere('firmId', '=', $this->firmId);

这同样适用于使用HasManyThrough的BmPerson的BmSecurity。
希望能有所帮助。

js5cn81o

js5cn81o4#

read laravel hasManyThrough关系。它将帮助您更容易地编写此查询
https://laravel.com/docs/5.1/eloquent-relationships#has-many-through

im9ewurl

im9ewurl5#

我知道这是一个很老的问题,但是我在一个客户的项目中得到了这个需求,我用类似where的方法解决了它。

$this->hasMany('BmCoverage', 'firmId', 'firmId', 'BmPerson')
 ->whereColumn('BmPerson.personId', '=', 'BmCoverage.personId');

我真的希望这个答案能帮助到一些人。

相关问题