Not sure if I should post this in this repo or the Fractal one, but whatever.
It appears that when fetching embedded resources, that happens after the parent resource is already fetched from the database. This means that if the parent has hundreds of items, fetching their embedded resources results in hundreds of db calls. Am I right, or am I missing something?
In my current project (not using Fractal at the moment), I have my repository (abstracted from my models) handle the query vars and if embeds are requested, they are immediately sent to the model (firing Actor::with(['movies'])->all()
) for eager loading.
Then, in my own transformer, I do something like this:
<?php namespace Services\Transformation;
class ActorTransformer extends BaseTransformer implements TransformerInterface {
protected $embedables = [
'images' => 'ImageTransformer',
'movies' => 'MovieTransformer'
];
// more code
The BaseTransformer:
<?php namespace Services\Transformation;
abstract class BaseTransformer {
/**
* The repositories that can be embedded in an instance of
* the current resource.
* @var array
*/
protected $embedables;
/**
*
*
* @param $instance object The parent repository (Eloquent)
* @param $data array The transformed data we need to add to
* @return array The data array with the embeds added to it
*/
protected function addEmbeds($instance, $data)
{
foreach ($this->embedables as $embed => $transformer) {
if (isset($instance->$embed)) {
$transformerName = __NAMESPACE__ . '\\' . $transformer;
$subResource = new $transformerName();
if ($subResource instanceof TransformerInterface) {
$data[$embed] = $subResource->transformCollection($instance->$embed);
}
}
}
return $data;
}
The transformer loops through all the $embedables, (which, I see now should be spelled with two d's), checks if the item has a property called 'images' or 'movies' and if so, that property will be parsed by its own transformer (which one it should load is specified in the associative array).
It's still in a very early stage, my own transformer project, but I thought I'd share.