You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Eloquent:五张数据表的关联关系实现方法咨询

Laravel Eloquent关联实现:users、user_location、cities、states、countries五表关联

嘿,我来帮你理清楚这五张表的Eloquent关联关系,其实按照数据层级一步步拆解就很清晰了,咱们逐个模型来写对应的关联方法:

1. Country模型

一个国家对应多个州,所以是一对多关联;同时可以通过hasManyThrough直接关联到城市(跳过州这一层):

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Country extends Model
{
    protected $table = 'countries';

    // 一个国家有多个州
    public function states(): HasMany
    {
        return $this->hasMany(State::class);
    }

    // 一个国家有多个城市(通过州间接关联)
    public function cities()
    {
        return $this->hasManyThrough(City::class, State::class);
    }
}

2. State模型

一个州属于某个国家,同时对应多个城市,分别是多对一和一对多关联:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class State extends Model
{
    protected $table = 'states';

    // 州属于某个国家
    public function country(): BelongsTo
    {
        return $this->belongsTo(Country::class);
    }

    // 一个州有多个城市
    public function cities(): HasMany
    {
        return $this->hasMany(City::class);
    }
}

3. City模型

城市属于某个州,同时通过user_location中间表和用户形成多对多关联;如果需要直接关联到国家,可使用belongsToThrough(注意版本兼容性):

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class City extends Model
{
    protected $table = 'cities';

    // 城市属于某个州
    public function state(): BelongsTo
    {
        return $this->belongsTo(State::class);
    }

    // 城市属于某个国家(通过州间接关联)
    // 注意:Laravel 9.x及以上原生支持belongsToThrough,低版本需安装staudenmeir/belongs-to-through包,或用join替代
    public function country()
    {
        return $this->belongsToThrough(Country::class, State::class);
    }

    // 城市关联多个用户(通过user_location中间表)
    public function users(): BelongsToMany
    {
        // 参数依次:关联模型、中间表名、中间表中当前模型的外键、中间表中关联模型的外键
        return $this->belongsToMany(User::class, 'user_location', 'cities_id', 'user_id');
    }
}

4. UserLocation模型(可选)

如果你的user_location表需要存储额外字段(比如关联时间、备注等),可以建立这个模型,用来直接操作中间表数据:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class UserLocation extends Model
{
    protected $table = 'user_location';
    public $timestamps = false; // 如果表没有created_at/updated_at字段,需设置为false

    // 关联用户
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    // 关联城市
    public function city(): BelongsTo
    {
        return $this->belongsTo(City::class, 'cities_id');
    }
}

5. User模型

用户通过user_location和城市形成多对多关联,也可以通过关联链直接获取到州和国家:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class User extends Model
{
    protected $table = 'users';

    // 用户关联多个城市(通过user_location中间表)
    public function cities(): BelongsToMany
    {
        return $this->belongsToMany(City::class, 'user_location', 'user_id', 'cities_id');
    }

    // 获取用户所在的所有州(通过城市间接关联)
    public function states()
    {
        return $this->hasManyThrough(State::class, City::class, 'id', 'id', 'id', 'state_id');
    }

    // 获取用户所在的所有国家(通过州和城市间接关联)
    public function countries()
    {
        return $this->hasManyThrough(Country::class, State::class, 'country_id', 'id', 'id', 'state_id');
    }

    // 如果使用了UserLocation模型,可直接关联中间表
    public function userLocations()
    {
        return $this->hasMany(UserLocation::class);
    }
}

关联使用示例

  • 获取某个用户的所有城市及对应的州和国家:
$user = User::with('cities.state.country')->find(1);
foreach ($user->cities as $city) {
    echo "{$city->name}, {$city->state->name}, {$city->state->country->name}\n";
}
  • 获取某个国家的所有州及下属城市:
$country = Country::with('states.cities')->find(1);
foreach ($country->states as $state) {
    echo "{$state->name}: ";
    foreach ($state->cities as $city) {
        echo "{$city->name} ";
    }
    echo "\n";
}

内容的提问来源于stack exchange,提问作者Kaushal Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 10:33:11