【问题标题】:Relationship between many-to-many table and other one-to-many table多对多表与其他一对多表的关系
【发布时间】:2019-03-20 18:26:14
【问题描述】:

大家早上好,

首先要说我使用的是 Laravel,因此,Eloquent ORM,但我认为这更像是一个纯粹的关系数据库问题(或不是),所以这就是我在这里提到它的原因。

有一段时间,我做了many-to-many表和一对多表的关系。

有这4个涉及的表:

  • “机器”(ID、名称、...)
  • “产品”(ID、名称、...)
  • 'machine_products'(id、machine_id、product_id、价格)。
  • “限制”(id、machine_product_id、day、begin_hour、end_hour)

特别是给定一台机器和一个产品,有 N 个限制。

到目前为止,我认为一切都很好,但是当我想将其转换为 Laravel 模型时,我开始怀疑。

原则上,我们应该有以下三种模型:

  • 机器
  • 产品
  • 限制
  • (MachineProduct???理论上不需要)

通常,不需要制作many-to-many 模型,因为它们可以通过两个主要模型之一访问。在这种情况下,我们可以从MachineProduct 访问数据透视表machine_products

当我想从MachineProduct 的实例中通过Eloquent 访问restrictions 时,问题就出现了。同样,我不知道如何通过restrictions的实例访问MachineProduct

我现在选择的一个选项是这样的,虽然它只解决了第一个问题:

Restriction::find(Machine::find(1)->products()->first()->pivot->id);

我们可以建议一个更优雅和实用的解决方案,以便从产品/机器中获得限制并向后?

谢谢!

编辑

我想要这样的东西:

Machine::find(1)->products()->first()->restrictions 或那个Product::find(1)->machines()->first()->[pivot?]->restrictions

我也希望能够做到这一点:Restriction::find(1)->[pivot?]->machine(或产品)

以下是三个模型:

class Machine extends Model
{
    public function products()
    {
        return $this->BelongsToMany('App\Product', 'machine_products')->withPivot('id','price');
   }
}


class Product extends Model
{  
    public function machines()
    {
        return $this->BelongsToMany('App\Machine', 'machine_products')->withPivot('price');
    }

}


class Restriction extends Model
{
    // Nothing
}

【问题讨论】:

  • 分享你的模型
  • 这里,内部评论?或者我用这三个人编辑帖子。
  • 你说你有一个“问题”,但你不清楚它是什么。拥有 ORM 定义的效果是创建某些表和约束。您不仅可以从声明模型中获得 2 个模型和一个数据透视表,还可以从模型和 M:M 声明中获得。从机器、产品和限制开始,您的机器产品或限制(机器产品)与您看到的任何 M:M 示例有何不同? PS请阅读minimal reproducible example并采取行动。 PS 通过后期编辑澄清为当前最佳形式,而不是通过 cmets。
  • 我编辑了这篇文章。我想要的是这样的:Machine::find(1)->products()->first()->restrictions。我也希望能够做到这一点:Restriction::find(1)->machine(或产品)
  • 谷歌“stackexchange 通知”以了解如何使用 @ 联系多个非发布者评论者之一。您的评论没有通知任何人。我路过。 PS 仍然没有设计或 MCVE。您的 Eloquent 关系声明在哪里?为什么期望有任何 M:M 表? (修辞。) PS请不要在旧版本中添加编辑。编辑您的帖子,使其成为现在最清晰的演示文稿。

标签: mysql laravel eloquent relational-database


【解决方案1】:

通常不建议(或不需要)在数据透视表中包含 id 列。

我会删除它并调整restrictions 表:idmachine_idproduct_id、...

这满足了您的第二个要求:Restriction::find(1)->machine

反向仍然是一个问题。我认为对此没有优雅的解决方案:

Restriction::where('machine_id', $machine_id)
    ->where('product_id', $product_id)
    ->get();

你可以用范围来简化它:

class Restriction extends Model {
    public function scopeByIds($query, $machine_id, $product_id) {
        $query->where('machine_id', $machine_id)
            ->where('product_id', $product_id);
    }
}

Restriction::byIds($machine_id, $product_id)->get();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 2018-01-11
    • 2019-10-15
    • 1970-01-01
    相关资源
    最近更新 更多