Laravel 数据透视表间关联:方案优劣及模型实现方法?
解决方案步骤
1. 数据库迁移(添加people_place_id字段)
先生成迁移文件:
php artisan make:migration add_people_place_id_to_people_things_table
打开生成的迁移文件,编写字段添加逻辑:
public function up() { Schema::table('people_thing', function (Blueprint $table) { $table->unsignedBigInteger('people_place_id')->nullable(); $table->foreign('people_place_id')->references('id')->on('people_place')->onDelete('cascade'); }); } public function down() { Schema::table('people_thing', function (Blueprint $table) { $table->dropForeign(['people_place_id']); $table->dropColumn('people_place_id'); }); }
执行迁移生效:
php artisan migrate
2. 模型关联定义
PeoplePlace 模型
namespace App\Models; use Illuminate\Database\Eloquent\Model; class PeoplePlace extends Model { protected $table = 'people_place'; // 关联所属用户 public function person() { return $this->belongsTo(People::class, 'people_id'); } // 关联对应地点 public function place() { return $this->belongsTo(Places::class, 'place_id'); } // 关联该记录下的所有物品 public function things() { return $this->hasMany(PeopleThing::class, 'people_place_id'); } }
PeopleThing 模型
namespace App\Models; use Illuminate\Database\Eloquent\Model; class PeopleThing extends Model { protected $table = 'people_thing'; // 关联对应的用户-地点记录 public function peoplePlace() { return $this->belongsTo(PeoplePlace::class, 'people_place_id'); } // 关联物品本身 public function thing() { return $this->belongsTo(Things::class, 'thing_id'); } // 间接关联所属用户 public function person() { return $this->hasOneThrough(People::class, PeoplePlace::class, 'id', 'id', 'people_place_id', 'people_id'); } }
People 模型
namespace App\Models; use Illuminate\Database\Eloquent\Model; class People extends Model { protected $table = 'people'; // 关联用户的所有地点记录 public function peoplePlaces() { return $this->hasMany(PeoplePlace::class, 'people_id'); } // 间接关联用户的所有物品 public function things() { return $this->hasManyThrough(PeopleThing::class, PeoplePlace::class, 'people_id', 'people_place_id', 'id', 'id'); } }
Things 模型
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Things extends Model { protected $table = 'things'; // 关联物品的所有持有记录 public function peopleThings() { return $this->hasMany(PeopleThing::class, 'thing_id'); } }
3. 常用操作示例
- 获取用户某地点记录下的所有物品
$targetPlaceRecord = People::find(1)->peoplePlaces()->where('place_id', 5)->first(); $itemsInPlace = $targetPlaceRecord->things;
- 获取某物品的所在地点及所属用户
$itemRecord = PeopleThing::find(3); $placeInfo = $itemRecord->peoplePlace->place; $ownerInfo = $itemRecord->peoplePlace->person;
- 创建关联特定地点记录的物品
$existingPlaceRecord = PeoplePlace::find(2); $existingPlaceRecord->things()->create([ 'thing_id' => 7, // 其他people_thing表的自定义字段 ]);
内容的提问来源于stack exchange,提问作者CptMisery
相关产品推荐
相关产品推荐

