How to cache select queries executed by relataion ?

I am building a REST-full API, but I think that question may apply even if you are building web application.

Here I will give you very simplified example of my real code, that is enough to backup my answer.

I have DocumentController responsible for allowing access to documents endpoint.

This is my relevant code there:




/**

 * Declares external actions for the controller.

 */

public function actions()

{

    $actions = parent::actions();


    // disable the "delete", "create" and update actions

    unset($actions['delete'], $actions['create'], $actions['update']);


    // for index action, customize the data provider preparation with the "prepareDataProvider()" method

    $actions['index']['prepareDataProvider'] = [$this, 'prepareDataProvider'];


    return $actions;

}


public function prepareDataProvider()

{

    /** @var $query ActiveQuery */

    $query = Document::find()->limit(5)->orderBy(['document.id' => SORT_DESC]);


    // execute query or serve it from cache

    $result = Document::getDb()->cache(function () use ($query) {

        return $query->all();

    });


    return $result;

}



And I have my models: Document and DocumentContent.

Here is the code of Document model:




public function fields()

{

    $fields = parent::fields();

    $fields[] = 'documentContent';

    return $fields;

}






/**

 * Relation with document_content table.

 * 

 * @return DocumentContent

 */

public function getDocumentContent()

{

    return $this->hasMany(DocumentContent::className(), ['document_id' => 'id']);

} 



As you can see I am declaring in fields() method that I always want documentContent relation returned in output.

By the way, I do not like this approach but I didn’t knew how to return documentContent in JSON output if I execute some relational query manually, and do not write in fields() that I want that relation returned. it seems to me that if I do not declare relation in fields() I can not get it in JSON response, even if I made my mega object myself that has documentContent property inside.

And my DocumentContent model has just relation with Document.




/**

 * Relation with document table.

 * 

 * @return Document

 */

public function getDocument()

{

    return $this->hasOne(Document::className(), ['id' => 'document_id']);

}



Because of these lines of code in my DocumentController, the query executed directly on document table will be cached and that is fine:




$result = Document::getDb()->cache(function () use ($query) {

    return $query->all();

});



But because of my relation with documentContent, there will be X ( where X is a limit ) SELECT queries executed all the time. For example:




SELECT * FROM `document_content` WHERE `document_id`=2347715



My question is: how can I get these SELECT by ID queries cached ? It seems to me that Yii is executing them on its own, because of $fields[] = ‘documentContent’; and I do not know how to get in control of that.

For me, it would be perfect if I can execute all the queries myself, and still be able to see relations in output. If not, I would like to get these SELECT queries, executed by Yii, cached.

Any idea how to do this ?

EDIT: can any moderator please fix the title of this topic ? It is not "relataion" it is "relation", I made a type and cant fix it on my own.