无法在Laravel中更新可翻译模型

问题描述

我正在使用https://github.com/Astrotomic/laravel-translatable使我的模型可翻译。

虽然我尝试使用以下方法更新模型,以更新模式及其相关的翻译内容

$product = $this->repository->update($input,$uuid);

   // output of dd($input);

  "uuid" => "44b26fb0-04b9-11eb-981a-6b01570d58ed"
  "_method" => "PUT"
  "en-us" => array:5 [▶]
  "ar-eg" => array:5 [▶]
  "account_uuid" => "a1c23ce0-04b7-11eb-b060-7faa78f23afd"
  "type" => "tour"
  "iso_4217" => "EGP"
  "status" => "pending"

我收到此错误

Column not found: 1054 UnkNown column 'id' in 'where clause'

根据以下模型设置,考虑模型主键是“ uuid”而不是“ id”,因此外键是“ product_uuid”而不是“ product_id”。

class Product extends Model implements Transformable,TranslatableContract
{
    public $incrementing = false;
    public $keyType = 'string';
    public $timestamps = true;
    protected $primaryKey = 'uuid';

    public $translatedAttributes = [
        'name','quantity_label_snigular','quantity_label_plural','brief_description','long_description','terms','Meta_keywords',];

    public $translationForeignKey = 'product_uuid';
    public $localeKey = 'uuid';    
    public $useTranslationFallback = true;    
}

尽管我无法跟踪该错误,但仍遵循此链接https://docs.astrotomic.info/laravel-translatable/usage/forms#saving-the-request上的确切文档。

解决方法

我发现问题出在productTranslation模型的设置中。

“ product_translations”表主键是“ product_uuid”和“ locale”的组合。

因此在“ ProductTranslation”模型中,我将主键定义为数组

protected $primaryKey = ['product_uuid','locale'];

并扩展了这些方法以从数组中获取主键,而不是根据此答案https://stackoverflow.com/a/37076437

    /**
     * Set the keys for a save update query.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    protected function setKeysForSaveQuery(Builder $query)
    {
        $keys = $this->getKeyName();
        if(!is_array($keys)){
            return parent::setKeysForSaveQuery($query);
        }

        foreach($keys as $keyName){
            $query->where($keyName,'=',$this->getKeyForSaveQuery($keyName));
        }

        return $query;
    }

    /**
     * Get the primary key value for a save query.
     *
     * @param mixed $keyName
     * @return mixed
     */
    protected function getKeyForSaveQuery($keyName = null)
    {
        if(is_null($keyName)){
            $keyName = $this->getKeyName();
        }

        if (isset($this->original[$keyName])) {
            return $this->original[$keyName];
        }

        return $this->getAttribute($keyName);
    }