fractal icon indicating copy to clipboard operation
fractal copied to clipboard

Recursive Transformers and Includes

Open JeanLucEsser opened this issue 9 years ago • 4 comments

I thought this would be trivial, but i'm stuck and cannot figure out if it is even possible to do what I ask. Here is my Transformer Class for a nested set, Division.

class DivisionTransformer extends TransformerAbstract
{

    protected $defaultIncludes = [
        'divisions'
    ];

    protected $availableIncludes = [
        'employees'
    ];

    public function transform(Division $division)
    {
        return [
            'id' => (int) $division->id,
            'name' => $division->name
        ];
    }

    public function includeDivisions(Division $division)
    {
        return $this->collection($division->children, new DivisionTransformer); 
        // ^^ if 'employees' include exists, i want it to persist to the division's children
    }

    public function includeEmployees(Division $division)
    {
        return $this->collection($division->employees, new EmployeeTransformer);
    }

}

The $defaultIncludes = 'divisions' is used for recursive reasons : a division can have divisions and so on. It's a tree structure (via Baum). It works great. No issue here.

When asking to include 'employees', the include works great on the first level division class. But not on its children.

Question is : if parseIncludes('division') has been set on the Manager, how do I tell my Transformer to persist it when default-including my division's children ?

PS: if I really missed something and this is not the place to ask for this, let me know and i'll create a StackExchange question.

JeanLucEsser avatar Sep 30 '15 15:09 JeanLucEsser

I found a way around it but I'm pretty sure it's bad practice...

First, in my controller, in place of calling parseIncludes('employees') on the Manager, I add my 'employees' include to the defaultIncludes property on my divisionTransformer instance via setDefaultIncludes().

Second, in order for the defaultIncludes property on my divisionTransformer to be recursively persisted, I changed the includeDivisions method to pass the current instance ($this) in place of a new DivisionTransformer:

    public function includeDivisions(Division $division)
    {
        return $this->collection($division->children, $this);
    }

Still, I consider this a bad solution and I'm sure you'll give me a better way of doing things.

Maybe via a Scope Class to access the Manager from the Transformer? I'm not familiar with Scope and found no documentation about it, I'll try to work something out.

Any comment is very welcomed.

JeanLucEsser avatar Sep 30 '15 18:09 JeanLucEsser

The way you have done it is the way I would suggest doing it for now. See the issue seems to be that when Fractal detects you want to include an available include, it only does it on the first transformer, when you nest transformers it looks like it doesn't listen for the includes.

I'll add this to v1.0.0!

willishq avatar Oct 16 '15 19:10 willishq

An old thread, but I have the exact same use-case and using the current instance ($this) for returning the collection isn't working for me. I'm missing type and all links for related objects. Am I missing something obvious here that has to be added, but not visible in the code by @JeanLucEsser above?

jonaholsson avatar Mar 10 '16 08:03 jonaholsson

This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 4 weeks if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Apr 16 '22 06:04 stale[bot]