覆盖强制转换方法,无法保存到数据库

时间:2019-07-12 13:42:30

标签: php laravel

我有以下型号:

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);
}

因此,在我的fieldables表中,我有一个contenttype列。内容可以是数组或字符串。这由type列确定。

为了确保Laravel在获取数据时强制转换正确的类型,我在FieldablePivot模型上使用以下代码:

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);
}

现在,当我这样做时:

foreach($document->fields as $field){
       dd($field->pivot->content);
}

它返回arraystring

但是,当我要将数据保存到数据库时,例如:

$document->cropped()->create([
   'field_id' => 8,
   'content' => "A string",
   'type' => 'string'
]);

我遇到以下错误:

  

找不到四位数的年份

1 个答案:

答案 0 :(得分:0)

问题是您的hasCasts()替代未考虑传入的$types。这使Laravel认为您的content属性可以转换为日期({{ 1}}始终会为isDateCastable()返回true,它会尝试执行并失败。

为避免这种情况,您可以覆盖content方法而不是getCasts()hasCast()方法。

getCastType()

现在,所有其他函数的行为就像将您的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; } 属性添加到模型的content数组中一样。

您还可以尝试使用模型mutators and accessors,但是最终您必须自己编写转换功能,而且我不知道是否在透视表上考虑了变数和访问器。