79486096

Date: 2025-03-05 10:12:35
Score: 0.5
Natty:
Report link

So the answer is complicated.

Like @Moshe Katz offered I created DummyClass and changed createModelByType().

  1. All my models extend CommonModel class, like Balance
class Balance extends CommonModel
{
    public $subject;
    public $subject_id;
    
    public function subjectable(): MorphTo
    {
        return $this->morphTo(__FUNCTION__, 'subject', 'subject_id');
    }
}
  1. In CommonModel I have overwrite method newMorphTo with my class App\Models\Replace\MorphTo
<?php
namespace App\Models;

use App\Models\Replace\MorphTo;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class CommonModel extends Model
{
    public function isDummy()
    {
        return false;
    }

    protected function newMorphTo(Builder $query, Model $parent, $foreignKey, $ownerKey, $type, $relation)
    {
        return new MorphTo($query, $parent, $foreignKey, $ownerKey, $type, $relation);
    }
}
  1. I have created app\Models\Replace\MorphTo.php class which return DummyClass:
<?php

namespace App\Models\Replace;

use App\Models\DummyClass;
use Illuminate\Database\Eloquent\Relations\MorphTo as IlluminateMorphTo;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Arr;

class MorphTo extends IlluminateMorphTo
{
    public function createModelByType($type)
    {
        $class = Arr::get(Relation::morphMap() ?: [], $type, DummyClass::class);

        return tap(new $class, function ($instance) {
            if (! $instance->getConnectionName()) {
                $instance->setConnection($this->getConnection()->getName());
            }
        });
    }
}
  1. Next we need DummyClass, that uses fake database.
<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class DummyClass extends Model
{
    protected $connection = 'sqlite_fake';

    public function isDummy()
    {
        return true;
    }
}
  1. Also we need to create that fake database in config/database.php
    'connections' => [

        'sqlite_fake' => [
            'driver' => 'sqlite',
            'database' => ':memory:',
            'prefix' => '',
        ],
    ...
  1. And finnaly we need to create empty table in memory. I put this code in AppServiceProvider boot() method.
        Schema::connection('sqlite_fake')->create('dummy_classes', function ($table) {
            $table->id();
        });
Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @Moshe
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: Levsha