Laravel: Как мне исправить эту черту (с атрибутами), чтобы она также работала при создании модели? - PullRequest
0 голосов
/ 18 октября 2019

Я использую черту для динамического добавления атрибутов электронной почты в модель. Это дает мне возможность повторно использовать код среди многих моделей. Однако этот код завершается неудачно, когда я пытаюсь создать новую модель (но успешно , когда я обновляю существующую модель).

Проблема заключается в предположении, что $ this-> id доступно в чертах / контактах / HasEmails> setEmailTypeAttribute. Идентификатор еще не доступен, потому что сохранение не завершено.

Мой вопрос: Как я могу исправить эту черту, чтобы она также работала при создании модели?

Google, без результатов Думая о чем-то о моделисобытия (статические :: создание ($ модель))

\ app \ Traits \ Contact \ HasEmails.php


 /*
     * EmailGeneric getter. Called when $model->EmailGeneric is requested.
     */
    public function getEmailGenericAttribute() :?string
    {
        return $this->getEmailTypeAttribute(EmailType::GENERIC);
    }

    /*
     * EmailGeneric setter. Called when $model->EmailGeneric is set.
     */
    public function setEmailGenericAttribute($email)
    {
        return $this->setEmailTypeAttribute(EmailType::GENERIC, $email);
    }

     /*
     * Get single e-mail model for model owner
     */
    private function getEmailTypeAttribute($emailType) :?string
    {
        $emailModel = $this->emailModelForType($emailType);
        return $emailModel ? $emailModel->email : null;
    }

    /*
    * Update or create single e-mail model for model owner
    *
    * @return void
    */
    private function setEmailTypeAttribute($emailType, $email) :void
    {
        $this->emails()->updateOrCreate([
            'owned_by_type' => static::class,
            'owned_by_id' => $this->id,
            'type' => $emailType
        ],['email' => $email]);
    }

\ app \ Models \ Email.php


namespace App\Models;

class Email extends Model
{

    public $timestamps = false;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'email'
    ];

    /*
     * Get polymorphic owner
     */
    public function ownedBy(): \Illuminate\Database\Eloquent\Relations\MorphTo
    {
        return $this->morphTo();
    }

    /*
     * Default attributes are prefilled
     */
    protected function addDefaultAttributes(): void
    {
        $attributes = [];
        $attributes['type'] = \App\Enums\EmailType::GENERIC;

        $this->attributes = array_merge($this->attributes, $attributes);
    }
}

\ migrations \ 2019_10_16_101845_create_emails_table.php

 Schema::create('emails', function (Blueprint $table) {
            $table->bigIncrements('id');

            $table->unsignedBigInteger('owned_by_id');
            $table->string('owned_by_type');

            $table->string('type');              //f.e. assumes EmailType
            $table->string('email');

            $table->unique(['owned_by_id', 'owned_by_type', 'type'], 'owner_type_unique');
        });

Я ожидаю, что связанная модель будет создана / обновлена, но при создании не получится.

1 Ответ

0 голосов
/ 22 октября 2019

Трюк использовал событие сохраненной модели, а также не забыл установить атрибут fillable для модели электронной почты:

/*
    * Update or create single e-mail model for model owner
    *
    * @return void
    */
    private function setEmailTypeAttribute($emailType, $email) :void
    {
        static::saved(static function($model) use($emailType, $email) {
            $model->emails()
                ->updateOrCreate(
                    [
                        'owned_by_type' => get_class($model),
                        'owned_by_id' => $model->id,
                        'type' => $emailType
                    ],
                    [
                        'email' => $email
                    ]);
            });
    }
...