0
votes

Problem

I have model having morphed relation and those different kind of relations have totally different json resources to return. So I'm trying to find out a way to resolve correct relation class and return it with the base model's resource.

For example if I have Comment and morphed relation "commentable" containing model instances of Car and Driver. Now, if I request some comment I would have be able to return correct json response stored into CarResource or PeopleResource.

{
    id: 1,
    text: 'A comment',
    commentable_type: 'Car', // could be car or driver
    commentable_data: {
        model: 'Ford',
        year: 2019
    },

    id: 2,
    text: 'An another comment',
    commentable_type: 'Driver',
    commentable_data: {
        name: 'Jon Doe',
        active: true
    },
}

Trying to solve

I tried to use following but got an error.

public function toArray($request)
{
    $modelClass = app(__NAMESPACE__ . '\\' . class_basename($this->commentable) . 'Resource');

    return [
        'id' => $this->id,
        'text' => $this->text,
        'commentable_type' => class_basename($this->commentable),
        'commentable_data' => new $modelClass($this->commentable),
    ];
}

If the resolved class doesn't exist I get of course

ReflectionException (-1)

Class App\Http\Resources\CarResource does not exist

But if the class exists, I get following error

Illuminate \ Contracts \ Container \ BindingResolutionException

Unresolvable dependency resolving [Parameter #0 [ $resource ]] in class Illuminate\Http\Resources\Json\JsonResource

Question

What do you think? Do you have any solution or recommendations e.g. how to manage this better?

1

1 Answers

0
votes

Ok, I found solution by digging a bit deeper into Laravel. Service Container is my friend. Like BindingResolutionException says I need to give $resource parameter to resolver using makeWith() function.

$modelClass = app()->makeWith(__NAMESPACE__ . '\\' . class_basename($this->barcodable) . 'Resource', [
    'resource' => $this->barcodable
]);

However, please let me know if somebody has anything thoughts about improving this.