首页 > 解决方案 > Laravel 通过具有价值的中间表关联 2 个模型

问题描述

我有以下架构

                                                                                                                                                                                                                                                                                                                                                                     CREATE TABLE `attributes` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
      `created_at` timestamp NULL DEFAULT NULL,
      `updated_at` timestamp NULL DEFAULT NULL,
      `deleted_at` timestamp NULL DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `records` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      `event_school_id` bigint(20) unsigned NOT NULL,
      `athlete_id` bigint(20) unsigned NOT NULL,
      `year` int(10) unsigned NOT NULL,
      `place` int(10) unsigned NOT NULL,
      `created_at` timestamp NULL DEFAULT NULL,
      `updated_at` timestamp NULL DEFAULT NULL,
      `deleted_at` timestamp NULL DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `records_event_school_id_foreign` (`event_school_id`),
      KEY `records_athlete_id_foreign` (`athlete_id`),
      CONSTRAINT `records_athlete_id_foreign` FOREIGN KEY (`athlete_id`) REFERENCES `athletes` (`id`),
      CONSTRAINT `records_event_school_id_foreign` FOREIGN KEY (`event_school_id`) REFERENCES `event_school` (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `attribute_record` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      `attribute_id` bigint(20) unsigned NOT NULL,
      `record_id` bigint(20) unsigned NOT NULL,
      `value` decimal(8,2) NOT NULL,
      `created_at` timestamp NULL DEFAULT NULL,
      `updated_at` timestamp NULL DEFAULT NULL,
      `deleted_at` timestamp NULL DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `attribute_record_attribute_id_foreign` (`attribute_id`),
      KEY `attribute_record_record_id_foreign` (`record_id`),
      CONSTRAINT `attribute_record_attribute_id_foreign` FOREIGN KEY (`attribute_id`) REFERENCES `attributes` (`id`),
      CONSTRAINT `attribute_record_record_id_foreign` FOREIGN KEY (`record_id`) REFERENCES `records` (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

如何在 laravel 中正确设置模型?对于attribute_record 表,属性和记录之间的关系中存在一个值。我想知道是否需要attribute_record 表的模型。

我希望能够做一些可以让 $record 获取属性及其值的事情。

foreach($record->attributes as $attr)
{
   echo $attr->value;
} 

这是我到目前为止所拥有的。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Attribute extends Model
{
    use SoftDeletes;
    protected $guarded = ['id'];

}

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Record extends Model
{
    use SoftDeletes;
    protected $guarded = ['id'];
}

标签: phplaraveleloquent

解决方案


我想知道是否需要attribute_record 表的模型。

不,这是一个数据透视表,当你正确设置关系时,Laravel 会透明地使用它。我假设这是一个多对多的关系(记录可以有很多属性,很多记录可以有相同的属性)所以定义你的关系,其余的由 Laravel 完成:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Attribute extends Model
{
    use SoftDeletes;
    protected $guarded = ['id'];
    public function records()
    {
        return $this->belongsToMany('\\App\\Record')
            ->withPivot('value')
            ->withTimestamps();
    }
}


<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Record extends Model
{
    use SoftDeletes;
    protected $guarded = ['id'];
    public function attributes()
    {
        return $this->belongsToMany('\\App\\Attributes')
            ->withPivot('value')
            ->withTimestamps();
    }
}

现在在控制器中你可以这样做:

$record = \App\Record::find($id);
foreach ($record->attributes as $attribute) {
    // $attribute is an instance of \App\Attribute
    // to access the values in the pivot table, use the pivot attribute
    echo $attribute->pivot->value;
}

推荐阅读