laravel - 与枢轴数据的多态关系
问题描述
我想解决以下问题:
我有多个模型,例如:
Product
Customer
每个模型都应该能够拥有一个或多个Fields
数据透视数据。
Field
:
id
title
type
required
例子:
Product
有一个名为 的字段video_url
,type
应该string
包含该pivot
值http://youtube.com/...
。
Customer
有一个名为 的字段external_id
,type
应该integer
包含该pivot
值242
。
字段应由用户动态添加。用户应该能够决定该字段是否正在变形Product
或Customer
(甚至更晚)。
也许这有助于理解:
我现在在做什么
目前我为每个人创建了一个新模型,product
并且customer
对于客户:
class CustomerField extends Model
{
/**
* @return \Illuminate\Database\Eloquent\Relations\belongsToMany
*/
public function customers()
{
return $this->belongsToMany(Customer::class)->withPivot('value');
}
}
对于产品:
class ProductField extends Model
{
/**
* @return \Illuminate\Database\Eloquent\Relations\belongsToMany
*/
public function products()
{
return $this->belongsToMany(Product::class)->withPivot('value');
}
}
目前这可行,但当然,这不是解决它的最优雅的方法。
我的问题
是否有可能将一个字段动态地变形为Product
或Customer
附加一个pivot
?
解决方案
我认为这就是你想要的多态:多对多
你不需要添加ProductField
和CustomerField
模型,
您只需要添加Product
,Customer
和Field
模型。
这些字段将动态地属于产品或客户 fieldable_type
。即使您有更多模型,它也会将模型名称存储到 this fieldable_type
。
您需要创建的表如下所示:
fieldables
表有fieldable_id
和fieldable_type
;
fieldable_type
将自动设置您的模型名称,例如App\Product
,您可以在以下位置自行自定义AppServiceProvider
:
Relation::morphMap([
'products' => 'App\Product',
'customers' => 'App\Customer',
]);
在产品型号中:
class Product extends Model
{
/**
* Get all of the fields for the product.
*/
public function fields()
{
return $this->morphToMany('App\Field', 'fieldable')->withPivot('value');
}
}
在客户模型中:
class Customer extends Model
{
/**
* Get all of the fields for the customer.
*/
public function fields()
{
return $this->morphToMany('App\Field', 'fieldable')->withPivot('value');
}
}
在现场模型中:
class Field extends Model
{
/**
* Get all of the products that are assigned this field.
*/
public function products()
{
return $this->morphedByMany('App\Product', 'fieldable');
}
/**
* Get all of the customers that are assigned this field.
*/
public function customers()
{
return $this->morphedByMany('App\Customer', 'fieldable');
}
}
具有枢轴值的 CRUD:
之后,您可以轻松地创建、获取、更新、删除枢轴值,例如:
Field::first()->products; # return the products with pivot value
Field::first()->customers; # return the customers with pivot value
Customer::first()->fields;
$field = Field::first();
# create new relationship with pivot value between customer and fields:
Customer::first()->fields()->attach($field, ['value' => 'customer new value field']);
# update pivot with value:
Customer::first()->fields()->sync([$field->id => ['value' => 'update customer value field']]);
# Delete pivot
Customer::first()->fields()->detach($field->id);
推荐阅读
- javascript - 即使在推送数据后,节点 js 也会得到空白 obj
- r - 如何使用 R 在时间序列图中输入天数?
- windows - Docker 命令未通过 Windows 上的 bash 脚本运行
- javascript - 有没有更简单的方法在 React 中设置状态?
- c++ - 使用 pre-SSE4 计算 vector2 double 的 floor 和 ceil
- python - 如何修复 TypeError: unhashable type: 'Column' in pyspark dataframe?
- python - 注释是否在运行时在 python 中解析?是否允许不定义?
- authentication - Spring security - Websphere 令牌身份验证以及 Spring 安全性
- javascript - 无法读取未定义的属性“xxx”-使用 axios
- loops - 如何在 SAS 循环中使用数据行而不是“卡片”?