I'm trying to use Polymorphic Relationships from this docs https://laravel.com/docs/12.x/eloquent-relationships#polymorphic-relationships
I have model Balance
class Balance
{
public $subject;
public $subject_id;
public function subjectable(): MorphTo
{
return $this->morphTo(__FUNCTION__, 'subject', 'subject_id');
}
}
Also I have simple mapping in AppServiceProvider
Relation::morphMap([
'shop' => 'App\Models\Shop',
'merchant' => 'App\Models\Merchant',
]);
So if the field subject contains 'shop' or 'merchant' - it works perfect.
But database is external resource, it's not strict like the code, and there might be some strings, that is not in my models and my app structure. And I can't control database and change it.
If subject contains string 'abc' , I'm getting an error: Class "abc" not found.
So it's impossible to use ->morphTo() in this case.
Is there a way to limit some "allowed list" of subjects (types), and return null or empty collection, if this subject not in my list?
UPD:
I can't make check $this->subject inside relation function, because it's null.
public function subjectable() {
var_dump($this->subject);
if (in_array($this->subject, ['shop', 'merchant'])) {
return $this->morphTo(__FUNCTION__, 'subject', 'subject_id');
}
return null;
}
I'm trying:
$result = $query->with(['subjectable'])->get(); // $this->subject is null
// or
$result = $query->get();
$result->load(['subjectable']); // $this->subject is null
You can create a dummy model that will be used for all types of data for which you do not have models, let's call it DummyModel.
You will need to extend Laravel's MorphTo model with your own version of the createModelByType method:
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());
}
});
}
(The Laravel original version of this method has $class = Model::getActualClassNameForMorph($type);, and there is no easy way to replace the static method on Model.)
This will return your DummyClass any time the morph map does not have a matching class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With