多态关系

时间:2018-09-03 03:45:16

标签: php laravel database-design eloquent

我有一个名为Product的主表,其中包含以下列:

   <Annotation Term="com.sap.vocabularies.Common.v1.FilterExpressionRestrictions" >
  <Collection>
     <Record>
        <PropertyValue Property="Property" PropertyPath="Customer" />
        <PropertyValue Property="AllowedExpressions" EnumMember="com.sap.vocabularies.Common.v1.FilterExpressionType/SingleValue" />
     </Record>
     <Record>
        <PropertyValue Property="Property" PropertyPath="CompanyCode" />
        <PropertyValue Property="AllowedExpressions" EnumMember="com.sap.vocabularies.Common.v1.FilterExpressionType/SingleValue" />
     </Record>
  </Collection>

“ id”和“ product_id”是唯一的(id是PK)

我将针对其他类型的产品(类型)使用其他表格。 所有其他这些表将具有产品的属性以及 取决于产品类型的其他属性 (即服装,记录等)。

所以我使用多态关系创建了一个产品模型 如下:

id
product_id
product_type
name
price
in_stock
upc

例如记录模型:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;


class Product extends Model
{
    protected $fillable = [
        'product_id',
        'product_type',
        'name',
        'price',
        'in_stock',
        'upc'
    ];

    public function categorizable()
    {
        return $this->morphTo();
    }
}

记录栏为:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Record extends Model
{
    protected $fillable = [
        'artist_id',
        'title',
        'label',
        'code',
        'format',
        'number_of_discs',
        'image',
        'description'
    ];

    public function products()
    {
        return $this->morphMany('\App\Product', 'categorizable');
    }

    public function artist()
    {
        return $this->belongsTo(Artist::class);
    }

    public function track()
    {
        return $this->hasMany(Track::class);
    }

    public function getItemDetails(int $itemId): array {

    }

}

这是我想到这些表的最佳方式。

我的问题是:

  1. 是否有更好的方法来解决此特定问题?

  2. 在这种情况下(使用多态关系),我将如何插入产品?

  3. 如何查询产品以从中返回数据 既有产品表又有记录表?我的意思是,不是原始查询 既然可以了,但是如何使用 有口才吗?

1 个答案:

答案 0 :(得分:1)

除了product_id中的Record列以外,您的代码是完美的。您不需要该列,只需将其删除

  

我将如何插入产品?

$product = Product::create([
            'name' => $request->name,
            'price' => $request->price,
            'in_stock' => $request->in_stock
        ]);

$record->products()->save($product);

OR

$record->products()->create([
                'name' => $request->name,
                'price' => $request->price,
                'in_stock' => $request-> in_stock,
                'product_id' => $record->id,
                'product_type' => get_class($record)
            ]);

如果您需要同时创建两者,则可以这样做

$record = Record::create([
          'artist_id' => $request->artist_id
          'title' => $request->title,
          'label' => $request->label,
          'code' => $request->code,
]);

$product = Product::create([
                'name' => $request->name,
                'price' => $request->price,
                'in_stock' => $request->in_stock
            ]);

$record->products()->save($product);
  

获取数据

$product = Product::with('categorizable')->find(2);
$product->categorizable; //this will be either Record, Cloth... instance

类似地记录

$record = Record::with('products')->find(1);
$record->products; //it will give you product collection

有关详细信息,您可以查看https://laravel.com/docs/5.1/eloquent-relationships#polymorphic-relations