Есть ли способ использовать поддельный класс (без таблицы/модели базы данных) для полиморфных отношений?

#laravel #eloquent #polymorphism #laravel-relations

Вопрос:

У меня есть transactions таблица, в которой есть типы транзакций , которые преобразуются в TopUpTransaction , DeductTransaction и т. Д., В которой содержится их конкретная информация (поскольку у них разные поля).

Теперь у меня есть тип транзакции SecurityDeposit , которому не нужна специальная модель, так как ему не нужна никакая дополнительная информация.

Я могу заставить его работать с морфингом по умолчанию, имея модель и таблицу бд, в которой хранится только id поле, но в этом нет смысла.

Есть ли способ обойти создание пустой модели и таблицы базы данных?

 class Transaction extends Model {

    public function transactionable(): MorphTo
    {
        return $this->morphTo();
    }

    public function text() 
    {
        return $this->transactionable->text()
    }

    public function class() 
    {
        return $this->transactionable->class()
    }
}
 
 class TopUpTransaction extends Model {

    public function text() {
        return "Top Up"
    }

    public function class() {
        return "text-success"
    }
}

class DeductTransaction extends Model {
 // has text() and class() methods 
}
 

Однако я не хочу создавать SecurityDepositTransaction в базе данных, так как для этого не потребуется никакой дополнительной информации

 class SecurityDepositTransaction { 
    
    public function text() {
        return "Security Deposit"
    }

    public function class() {
        return "text-danger"
    }
}
 

Комментарии:

1. Создайте классический класс морфов (а не красноречивое отношение морфов), расширяющее преобразование. вам придется установить некоторые атрибуты, такие как $table и тому подобное, возможно, перегрузить другие отношения. Для связи вы можете просто вернуть новый экземпляр SecurityDeposit с атрибутом класса intanciated Transaction

2. @N69S Что вы подразумеваете под классом морфологии? Не могли бы вы, пожалуйста, написать это в разделе ответов, показывающем ваш подход?

Ответ №1:

классическая полиморфная связь между позицией безопасности и транзакцией

 class SecurityDeposit extends Transaction
{
    protected $table = 'transactions';
    
    // and use it as if you use Transaction, but it will be a seperate class
    // if for example, this class has a special relation that Transaction doesnt have,
    // you declare it here. same for any speccific method to this class

    public function specialRelation() {
        return $this->hasMany(AnotherClass::class);
    }

    public function getDepositAmounr() {
        return $this->custom_data;
    }
}
 

Комментарии:

1. Я не думаю, что этот подход будет работать $user->transaction->transactionable как для моделей, так и для немоделей. Я что-то упускаю?

2. это не будет работать как красноречивый полиморф. для этого вам нужно использовать красноречивый полиморф.