-
-
Notifications
You must be signed in to change notification settings - Fork 21
Allow custom type resolution when creating polymorphic relationships #72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
How about if I add the ability to define a callback within a relationship definition, that resolves a related model to its resource type. Something like this: ToOne::make('example')
->type(['type1', 'type2'])
->resolve(fn($model) => $model->foo ? 'type1' : 'type2'), |
I found a solution that is a bit hackish but works in our case. Instead of using I think your suggestion is good though, but maybe wait and see if anyone else runs into this issue? |
I've got a more comprehensive solution for this one coming soon. Also will enable heterogeneous collection URLs so eg. you can have |
With the recent addition of Collections there are now two solutions for this.
use Tobyz\JsonApiServer\Resource\CollectionInterface;
class FooCollection implements CollectionInterface
{
public function name(): string
{
return 'foo';
}
public function resources(): array
{
return ['type1', 'type2'];
}
public function resource(object $model, Context $context): ?string
{
return $model->foo ? 'type1' : 'type2';
}
public function endpoints(): array
{
return [];
}
}
$api->collection(new FooCollection()); ToOne::make('example')
->collection('foo')
->required()
->writable()
->includable()
use Tobyz\JsonApiServer\Resource\Resource;
class Type1Resource extends Resource
{
// ...
public function resource(object $model, Context $context): ?string
{
return $model->foo ? $this->type() : null;
}
}
class Type2Resource extends Resource
{
// ...
public function resource(object $model, Context $context): ?string
{
return $model->bar ? $this->type() : null;
}
} ToOne::make('example')
->type(['type1', 'type2']) // "type" is now just an alias for "collection"
->required()
->writable()
->includable() |
Docs updated |
As mentioned in #68 (comment), I use simple
stdClass
objects to represent my data models inside theResource
classes.I'm now trying to create a polymorphic
ToOne
relationship like this:The example types
type1
andtype2
are also registered as resources on theJsonApi
class.Now when I try to create a new instance of a resource with this relationship, I get:
(Thrown here: https://github.com/tobyzerner/json-api-server/blob/main/src/Serializer.php#L156-L158)
It seems to me that the
Serializer
is trying to determine the resource class related to the included model, but because it's alwaysstdClass
it cannot differentiate between the various models being returned.Taking a closer look at the documentation, I see that I should also define the model classes as keys in the
type()
call: https://tobyzerner.github.io/json-api-server/relationships.html#polymorphic-relationshipsHowever, since all my models are plain
stdClass
objects, this is obviously not possible.Is there a workaround possible, aside from creating a class for every one of my models? As mentioned in the previously linked issue I didn't do that because we already have classes for all of our models, but they're not usable in
newModel()
because they have some required properties that are not available there. And introducing a second class for every model is a lot of extra work.Looking at theEdit: This was because of how we used to implement our models.Serializer::addIncluded()
that callsresourceForModel()
, I see that$model
is also available there and it already contains thetype
as a property (at least in our case).The text was updated successfully, but these errors were encountered: