【问题标题】:Laravel Model Relationships - What kind of relationship am I trying to create?Laravel 模型关系 - 我想建立什么样的关系?
【发布时间】:2025-12-14 07:15:01
【问题描述】:

我有 3 个与此问题相关的模型;国家、制造商和地区。

为了这个问题,我已经简化了表格。我认为表格中的任何其他内容或任何其他模型都与该问题无关。

我的桌子是这样设置的;

manufacturers
 - id
 - name

countries
 - id
 - name

regions
 - id
 - name
 - manufacturer_id
 - country_id

我想要做的是在我的刀片中写$manufacturer->countries 并让它吐出与给定制造商相关的国家/地区。

模型目前是这样相互关联的;

Country.php

public function manufacturers()
{
    return $this->hasMany(Manufacturer::class);
}

public function regions()
{
    return $this->hasMany(Region::class);
}

Region.php

public function manufacturer()
{
    return $this->belongsTo(Manufacturer::class);
}

public function country()
{
    return $this->belongsTo(Country::class);
}

以及我遇到问题的地方,Manufacturer.php

我认为我需要一个 hasMany 关系。我已经有了;

public function regions()
{
    return $this->hasMany(Region::class);
}

我会认为我会需要;

public function countries()
{
    return $this->hasManyThrough(Country::class,Region::class);
}

但这会导致这个错误;

Column not found: 1054 Unknown column 'countries.region_id' in 'on clause' (SQL: select `countries`.*, `regions`.`manufacturer_id` as `laravel_through_key` from `countries` inner join `regions` on `regions`.`id` = `countries`.`region_id` where `regions`.`manufacturer_id` = 4)

所以我尝试交换课程来给予;

public function countries()
{
    return $this->hasManyThrough(Region::class,Country::class);
}

但这会导致;

Column not found: 1054 Unknown column 'countries.manufacturer_id' in 'field list' (SQL: select `regions`.*, `countries`.`manufacturer_id` as `laravel_through_key` from `regions` inner join `countries` on `countries`.`id` = `regions`.`country_id` where `countries`.`manufacturer_id` = 4)

有谁知道我应该如何建立我的关系以实现我想要的?

我还尝试了belongsToMany 关系,它确实带回了国家,但同一个国家的多个实例。我只想要任何给定制造商的区域表中出现的每个国家/地区的一个实例。

【问题讨论】:

  • 据我所知,如果我错了,请纠正我,一个manufacturer 可以在多个countries 中,一个country 可以有多个manufacturersregions 表只是一个连接器表,没有实际价值。我对吗?因为如果是这种情况,那么您将需要Many to many 关系。
  • 嗨,区域表确实有一些价值。我稍微编辑了我的问题,以反映所有表都有一个名称字段这一事实,这很重要。制造商可以是多个国家/地区的一部分,每个国家/地区都分为几个区域,所以目前我有一个制造商在一个国家有 4 个区域,在不同的国家也可能有 4 个(任意数量),并且等等……
  • 请用所有有关系的模型更新你的答案。
  • @sumeet 有 8 个模型,问题会超过 1 公里。在这种情况下,我真的认为它没有必要或适用于这个问题。我还有一些用户可以拥有 region_id,具体取决于他们是否是区域经理并负责该区域以及为给定制造商在区域内进行的约会。经销商也位于给定制造商的单个区域中。不过,我认为这对这种特殊的关系并不重要。
  • @JordanD 我的意思是用 belongsToMany 关系更新当前问题。 $manufacturer->countries 将返回您的收藏。请检查收集文件。 unique :)

标签: php laravel relationship


【解决方案1】:

您实际上是在处理多对多关系。

在您的情况下,regions 是一个数据透视表。

请检查belongsToMany。

【讨论】:

    【解决方案2】:

    Laravel 中,应用的最佳关系是many to many 关系。这意味着应用于您的案例是 1 country 可以有多个 manufacturers 和 1 manufacturer 可以在多个国家。

    如果是这样的话,你不需要创建regions表,而是pivot table. laravel中默认的命名约定是(单数和om字母顺序),即country_manufacturer表它将包含(您始终可以添加一个称为pivot 值的额外变量):

    country_manufacturer
      - id
      - name // pivot value
      - manufacturer_id
      - country_id
    

    然后,在模型中,添加belongsToMany关系,即

    在制造商模型中(没有枢轴):

    public function countries()
    {
       return $this->belongsToMany(Manufacturer::class);
    }
    

    在国家模型中(有支点):

    public function manufacturers()
    {
       return $this->belongsToMany(Country::class)->withPivot('name');
    }
    

    因此,您可以致电$country->manufacturers(),它会为您提供$country 中所有制造商的列表,反之亦然:$manufacturer->countries 将为您提供制造商所在的所有国家/地区。

    【讨论】:

    • 好的,我明白你在说什么,谢谢你的回复。我刚刚将区域用作数据透视表,它的结构与您的 country_manufacturer 表相同,但是当我回显 foreach($manufacturer->countries as $country) 时,它会带回该国家/地区的 4 个实例,因为有给定制造商在该国家/地区的 4 个地区。我只希望它带回每个国家/地区的 1 个实例。你知道我是怎么做的吗?
    • 顺便问一下……你是不是把课弄错了?即国家()属于ToMany(国家::类)。这就是我正在使用的,因为这似乎可以让这个国家(太多的实例)回归。