I have below model:
Document.php
/**
* Get all of the documents field content.
*
* @return Illuminate\Database\Eloquent\Model
*/
public function fields()
{
return $this->morphToMany(Field::class, 'fieldable')
->using('App\FieldablePivot')
->withPivot(['content', 'type'])
->withTimestamps();
}
public function cropped()
{
return $this->hasMany(CroppedDocumentField::class);
}
So in my fieldables
table, I have a content
and type
column. The content can be either an array or a string. This is determinted by the type
column.
In order to make sure that Laravel casts the correct type when getting the data, I use below code on the FieldablePivot
model:
public function hasCast($key, $types = null)
{
if ($key === 'content') {
return true;
}
return parent::hasCast($key, $types);
}
protected function getCastType($key)
{
if ($key == 'content' && !empty($this->type)) {
return $this->type;
}
return parent::getCastType($key);
}
Now when I do:
foreach($document->fields as $field){
dd($field->pivot->content);
}
It returns either an array
or string
.
However, when I want to save data to the database, like:
$document->cropped()->create([
'field_id' => 8,
'content' => "A string",
'type' => 'string'
]);
I get below error:
A four digit year could not be found Data missing
The issue is that your hasCasts()
override is not taking into account the $types
passed in. This causes Laravel to believe that your content
attribute can be cast to a date (isDateCastable()
will always return true for content
), which it attempts to do and fails.
To avoid this, you could just override the getCasts()
method instead of the hasCast()
and getCastType()
methods.
public function getCasts()
{
$casts = parent::getCasts();
// Add your dynamic cast type to the returned $casts array.
if (!empty($this->type)) {
$casts['content'] = $this->type;
}
return $casts;
}
Now all the other functions will behave as if your content
attribute were added to the model's casts
array.
You could also attempt to use model mutators and accessors, however you would end up having to write the casting functionality yourself, and I don't know if mutators and accessors are taken into account on pivot tables.