douzi8916 2019-07-12 13:42
浏览 280
已采纳

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

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

  • 写回答

1条回答 默认 最新

  • dougai8673 2019-07-12 17:42
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 关于URL获取的参数,无法执行二选一查询
  • ¥15 液位控制,当液位超过高限时常开触点59闭合,直到液位低于低限时,断开
  • ¥15 marlin编译错误,如何解决?
  • ¥15 有偿四位数,节约算法和扫描算法
  • ¥15 VUE项目怎么运行,系统打不开
  • ¥50 pointpillars等目标检测算法怎么融合注意力机制
  • ¥20 Vs code Mac系统 PHP Debug调试环境配置
  • ¥60 大一项目课,微信小程序
  • ¥15 求视频摘要youtube和ovp数据集
  • ¥15 在启动roslaunch时出现如下问题