Laravel 与复合外键的关系

Posted

技术标签:

【中文标题】Laravel 与复合外键的关系【英文标题】:Laravel relations with composite foreign keys 【发布时间】:2020-08-13 12:37:42 【问题描述】:

这就是我想要实现的,我们有员工,每个员工可以有一个部门的职位,一个部门的一个职务和多个多个部门的额外费用,每个部门一个额外费用。我想将所有职责存储在staff_responsibilities 表中

我有一个staff 表,其中包含以下列

身份证 姓名 电子邮件

然后我有staff_responsibilities 包含以下列的表:

staff_id designation_id department_id responsibility_type_id

职责类型可以是PositionAdditional Charge,并且一名员工可以拥有多个Additional Charge 职责。

然后我有一个responsibility_types 表,其中包含以下列:

身份证 姓名

// I have no way to tell this relationship to look for a responsibility type 2 (2 is the id of the responsibility called `Designation`) 

public function designation()
    
        return $this->hasOne(StaffResponsibility::class);
    

// I have no way to tell this relationship to look for a responsibility type 2 
    public function position()
    
        return $this->hasOne(StaffResponsibility::class);
    

// Gives error: Syntax error or access violation: 1066 Not unique table/alias: 'staff_responsibilities' 
    public function additionalCharges()
    
        return $this->belongsToMany(StaffResponsibility::class, 'staff_responsibilities','designation_id');
    

任何帮助将不胜感激。

员工职责表

责任类型表

名称表

【问题讨论】:

我不明白你为什么要使用 compoships 包。看起来像正常的 hasOne、HasMany 和 ManyToMany 关系。 看起来一切正常。你有什么问题? 问题是它没有按我的意愿工作。这就是我想要的:当我执行 $staff->position 时,它应该返回第一个具有 responsibility_type_id 1(位置)的职责,而当我执行 $staff->designation 时,它应该返回第一个具有response_type_id 2(指定)的职责现在当我调用 $staff->position 或 $staff->designation 时,我无法告诉我的关系寻找特定的 responsibility_type_id。他们只返回与responsibility_id 和staff_id 匹配的第一条记录 【参考方案1】:

这就是我想要实现的目标,我们有员工,每个员工可以为一个部门担任一个职位,为一个部门担任一个职务,为多个部门担任多个附加费用,每个附加费用一个部门。

在我看来,为职位指定附加费用创建一个模型会很有好处。感觉您可能需要normalize your database 或将staff_responsibilities 更改为pivot table。

但如果不了解您的应用程序就很难说。

要回答您的问题,您可以在 StaffResponsibility 中添加一些范围

class StaffResponsibility extends Model

    public function scopeDesignation($query)
    
        return $query->where('responsibility_type_id','=',2);
    


并使用它

public function designation()

    return $this->hasOne(StaffResponsibility::class)->designation();

根据你写的,最后一个是 hasMany 关系,而不是 manyToMany:

public function additionalCharges()

    return $this->belongsTo(StaffResponsibility::class, 'staff_responsibilities','designation_id')->additionalCharges();

【讨论】:

指定和职位有效。谢谢!但是additionalCharegs 不起作用,我相信这将是一个 HasMayn 关系。但同样的问题,它会显示所有的责任。 我使用了相同的scope 方法,并且通过additionalCharges 获得了预期的结果; public function additionalCharges() return $this->hasMany(StaffResponsibility::class)->additionalCharges(); @JunaidQadir 你为什么取消选中这个? @JunaidQadir 我读到你更新了。您的权利很笨拙,但它是您原始帖子的正确答案。我已经说过,在我看来,您应该将Models 用于PositionDesignation 等似乎是更好的方法,这也会导致$staff->designation->name 等。而且我发现修改非常粗鲁你的问题,然后取消选中我的答案。如果您有新问题,请改为提出新问题。也许你的新问题更适合codereview.stackexchange.com @JunaidQadir 你的问题更新只要OP。我建议您 1) 创建一个新问题 2) 尽量减少示例 - 只需说明人员、职位和指定的问题。显示每个类的代码。我的猜测是,staff_responsibilities 不应该是模型,而是数据透视表,请参阅 laravel.com/docs/7.x/eloquent-relationships#many-to-many,但我在黑暗中猜测

以上是关于Laravel 与复合外键的关系的主要内容,如果未能解决你的问题,请参考以下文章

复合键的 Laravel 验证

没有外键的laravel关系

Laravel - Eloquent - 获得没有外键的关系

将包含外键的列添加到 Laravel 生产中的现有表中

Laravel - 如何将外键用于具有识别外键的表?

删除包含外键的字段,而不删除该字段包含LARAVEL的所有项目