I would like to solve the following issue:
I got multiple models like:
ProductCustomerEach model should be able to have one or more Fields with pivot data.
Field:
idtitletyperequiredExample:
Product has a field called video_url, type should be string containing the pivot value http://youtube.com/....
Customer has a field called external_id, type should be integer containing the pivot value 242.
The fields should be added dynamically by the user. The user should be able to decide, whether the field is morphing to Product or Customer (or even more later).
Maybe this helps to understand:

What I am doing right now
At the moment I created a new Model for each, product and customer
For customers:
class CustomerField extends Model
{
/**
* @return \Illuminate\Database\Eloquent\Relations\belongsToMany
*/
public function customers()
{
return $this->belongsToMany(Customer::class)->withPivot('value');
}
}
For products:
class ProductField extends Model
{
/**
* @return \Illuminate\Database\Eloquent\Relations\belongsToMany
*/
public function products()
{
return $this->belongsToMany(Product::class)->withPivot('value');
}
}
At the moment this works out, but of course, it's not the most elegant way to solve it.
My question
Is there a possibility to morph a field dynamically to Product or Customer with an additional pivot?
I think this is what you want Polymorphic:Many-to-Many
You don't need to add ProductField and CustomerField models,
you just need to add Product, Customer and Field model.
The fields will dynamically belongs to product or customer by fieldable_type. Even you have more models, it will store the model name to this fieldable_type.
And the tables you need to be created like this below:

fieldables table has fieldable_id and fieldable_type;
fieldable_type will set your model name automatically, like App\Product, and you can custom that by yourself in 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');
}
}
After that, you can easily create, get, update, delete pivot value like:
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With