dongyi1748 2019-05-16 02:43
浏览 59
已采纳

与多键主键的多态关系 - >未找到自动映射属性

I am setting up a parent->n-children model relationship (multi table) for a medical clinic and trying to automatically map the parent data. I am getting an array_key_exists(): The first argument should be either a string or an integer error.

I am following along with this tutorial: https://design-patterns12.blogspot.com/2018/01/laravel-model-inheritance-through.html

The DB relationship is: Episode (PK'['audit', 'episode', 'mrn']') Abstract Ward One of five different types of Ward. Each of these has ~100 fields that are independent of each other and the Episode parent.

class Episode extends Model
{
    use HasCompositePrimaryKey;

    protected $table = 'episodes';
    protected $primaryKey = ['audit', 'episode', 'mrn'];
    public $incrementing = false;
    protected $fillable = ['audit', 'episode', 'mrn'];
    protected $ward_fields = [];
    public $timestamps = false;

    public function audit()
    {
        return $this->belongsTo($this->audit(), 'id');
    }

    public function ward()
    {
        return $this->morphTo();
    }

    public function __get($name) {
        $ret = parent::__get($name);

        if ($ret === null) {

            if (isset($this->ward_fields[$name])) {
                $ret = $this->ward_fields[$name];
            } else if (array_key_exists('ward', $this->getRelations())) {
                $ret = $this->ward->{$name};
            }
        }

        return $ret;
    }

    public function __toString() {
        return $this->audit . ' ' . $this->episode . ' ' . $this->mrn;
    }
}

Abstract Class

<?php

namespace App;
use Illuminate\Support\Facades\Schema;

abstract class Ward extends Episode
{
    public $timestamps = false;
    protected $episode_fields = [];

    public function parent_episode()
    {
        return $this->morphOne(Episode::class, 'ward');
    }

    public function __get($name)
    {
        $ret = parent::__get($name);

        if ($ret === null) {
            if (isset($this->episode_fields[$name])) {
                $ret = $this->episode_fields[$name];
            } else if ($this->parent_episode()->count() > 0) {
                $ret = $this->episode->{$name};
            }
        }

        return $ret;
    }

    public function __set($key, $value)
    {
        if (!Schema::hasColumn($this->getTable(), $key)) {
            $this->episode_fields[$key] = $value;
        } else {
            parent::__set($key, $value);
        }
    }

    public function __unset($key)
    {
        if (!Schema::hasColumn($this->getTable(), $key)) {
            unset($this->episode_fields[$key]);
        } else {
            parent::__unset($key);
        }
    }

    public function __isset($key)
    {
        if (!Schema::hasColumn($this->getTable(), $key)) {
            return isset($this->episode_fields[$key]);
        } else {
            return parent::__isset($key);
        }
    }

    public function save(array $options = array())
    {
        $ret = parent::save($options);

        if ($ret) {
            $episode = $this->episode;


            if ($episode == null) {
                $episode = new Episode;
            }

            foreach ($this->episode_fields as $key => $value) {
                $episode->{$key} = $value;
            }

            $episode->save();

            $this->parent_episode()->save($episode);
        }

        return $ret;
    }

    public function delete()
    {
        $ret = false;

        if ($this->episode->delete()) {
            $ret = parent::delete();
        }

        return $ret;
    }

}

Example.test Rehabilitation ward

namespace App\Ward;
use App\Ward;

class Rehabilitation extends Ward
{
    protected $table = 'rehabilitations';
    protected $with = ['episodes'];
    protected $fillable = ['audit', 'episode', 'mrn'];
    public $timestamps = false;
}

this all seems to go well until I run the seed and stumble at the save() method

 ErrorException  : array_key_exists(): The first argument should be either a string or an integer

  at /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:317
    313| 
    314|         // If the attribute exists in the attribute array or has a "get" mutator we will
    315|         // get the attribute's value. Otherwise, we will proceed as if the developers
    316|         // are asking for a relationship's value. This covers both types of values.
  > 317|         if (array_key_exists($key, $this->attributes) ||
    318|             $this->hasGetMutator($key)) {
    319|             return $this->getAttributeValue($key);
    320|         }
    321| 

  Exception trace:

  1   array_key_exists([])
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:317

  2   Illuminate\Database\Eloquent\Model::getAttribute()
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php:376

  3   Illuminate\Database\Eloquent\Relations\HasOneOrMany::getParentKey()
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php:70

  4   Illuminate\Database\Eloquent\Relations\HasOneOrMany::addConstraints()
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/MorphOneOrMany.php:51

  5   Illuminate\Database\Eloquent\Relations\MorphOneOrMany::addConstraints()
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Relation.php:71

  6   Illuminate\Database\Eloquent\Relations\Relation::__construct(Object(Illuminate\Database\Eloquent\Builder), Object(App\Ward\Rehabilitation))
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php:46

  7   Illuminate\Database\Eloquent\Relations\HasOneOrMany::__construct(Object(Illuminate\Database\Eloquent\Builder), Object(App\Ward\Rehabilitation), "episodes.ward_id")
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/MorphOneOrMany.php:40

  8   Illuminate\Database\Eloquent\Relations\MorphOneOrMany::__construct(Object(Illuminate\Database\Eloquent\Builder), Object(App\Ward\Rehabilitation), "episodes.ward_type", "episodes.ward_id")
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php:158

  9   Illuminate\Database\Eloquent\Model::newMorphOne(Object(Illuminate\Database\Eloquent\Builder), Object(App\Ward\Rehabilitation), "episodes.ward_type", "episodes.ward_id")
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php:143

  10  Illuminate\Database\Eloquent\Model::morphOne("App\Episode", "ward")
      /Users/doug/Code/Snap/app/Ward.php:14

  11  App\Ward::parent_episode()
      /Users/doug/Code/Snap/app/Ward.php:77

  12  App\Ward::save()
      /Users/doug/Code/Snap/database/seeds/Ward/RehabilitationTableSeeder.php:31

  13  RehabilitationTableSeeder::run()
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32

  14  call_user_func_array([])
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32

  15  Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:90

  16  Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Object(Closure))
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:34

  17  Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), [])
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Container/Container.php:576

  18  Illuminate\Container\Container::call()
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Database/Seeder.php:122

  19  Illuminate\Database\Seeder::__invoke()
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Database/Seeder.php:42

  20  Illuminate\Database\Seeder::call("RehabilitationTableSeeder")
      /Users/doug/Code/Snap/database/seeds/DatabaseSeeder.php:18

  21  DatabaseSeeder::run()
      /Users/doug/Code/Snap/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32

I was expecting that the success the person in the tutorial I was following could be replicated.

I can see a couple of issues in the code that I do not quite understand: In the Ward class, The save() method has a $this->episode magic variable that I am not sure how it gets set. It also returns an integer while I would have expected that it returns an (Episode) object.

Can someone help shed some light on this?

  • 写回答

1条回答 默认 最新

  • duan3019 2019-07-22 04:06
    关注

    The final answer on this is that Eloquent can support multi key primary keys, Laravell can not. Thats it really.

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

报告相同问题?

悬赏问题

  • ¥15 关于大棚监测的pcb板设计
  • ¥20 sim800c模块 at指令及平台
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题
  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计