Eager load form relations
Created 7 years ago by pepijn

Hi,

I know I can eager load stuff in a TableBuilder, using the syntax below, but it seems this is not respected for the FormBuilder. As a result, a ton of queries get executed, and this admin page feels really slow.

How can I eager load form relations ?

 protected $options = [
        'eager' => [
            'translations',
            'relatedModel',
        ],
    ];
eager_load_forms.png
ryanthompson  —  7 years ago

You can eager load relations using protected $with = [relations]; in your model just like normal Laravel.

vargvinter  —  6 years ago

@ryanthompson - What am I doing wrong? I have ObjectModel and SystemModel. SystemModel belongsToMany ObjectModel. I eager load relationship:

class ObjectModel extends PortfolioObjectsEntryModel implements ObjectInterface
{
    protected $with = [
        'systems'
    ];
}

Then, in some dummy controller:

class PortfolioController extends Controller
{
    public function index()
    {
        $object = ObjectModel::first();

        return $object;
    }

systems relationship is not loaded. I don't see this field. What am I missing?

pepijn  —  6 years ago

@vargvinter Did you define your relationship as a PyroCMS field (in the migration), or did you add the belongsToMany relationship yourself, on the SystemModel ?

If you defined it in the migration, PyroCMS adds the relationship on the EntryModel (SystemEntryModel), and is able to eager load it in the TableBuilder. Since PyroCMS uses the EntryModel by default in the TableBuilder, if you defined it on the model yourself, PyroCMS doesn't know about this relation while rendering the table. In this case, you might be able to add protected $model = SystemModel::class; as a property to your TableBuilder (haven't tested this)

vargvinter  —  6 years ago

Hello @pepijn - check out the code.

Fields definition:

class LizardModulePortfolioCreatePortfolioFields extends Migration
{

    /**
     * The addon fields.
     *
     * @var array
     */
    protected $fields = [
        'name' => 'anomaly.field_type.text',
        'systems' => [
            'type' => 'anomaly.field_type.multiple',
            'config' => [
                'related' => SystemModel::class
            ]
        ],
    ];

}

Objects migration:

class LizardModulePortfolioCreateObjectsStream extends Migration
{

    /**
     * The stream definition.
     *
     * @var array
     */
    protected $stream = [
        'slug' => 'objects',
        'title_column' => 'name',
        'translatable' => true,
        'trashable' => false,
        'searchable' => false,
        'sortable' => false,
    ];

    /**
     * The stream assignments.
     *
     * @var array
     */
    protected $assignments = [
        'name' => [
            'translatable' => true,
            'required' => true,
        ],
        'systems' => [
            'required' => true,
        ],
    ];

}

Systems migration:

class LizardModulePortfolioCreateSystemsStream extends Migration
{

    /**
     * The stream definition.
     *
     * @var array
     */
    protected $stream = [
        'slug' => 'systems',
        'title_column' => 'name',
        'translatable' => true,
        'trashable' => false,
        'searchable' => false,
        'sortable' => false,
    ];

    /**
     * The stream assignments.
     *
     * @var array
     */
    protected $assignments = [
        'name' => [
            'translatable' => true,
            'required' => true,
        ]
    ];
}

In the ObjectModel I just added $with array to load systems relationship as described in my earlier post.