Containable and deep associated data

2019-08-19 06:17发布

document has many document_item
document_item has many document_item_description and belongs to document
document_item_description has one document_item

I'm trying to get a document with all document_items and all associated document_item_descriptions for the associated document_items

Is there a way to do this? Right now all I can get are document_items but can't get down to the third level.

        class Document extends AppModel {
        public $hasMany = array(
            'Document_item' => array(
                'className' => 'document_item',
                'foreignKey' => 'document_id'
                )
            );



    class DocumentItem extends AppModel {
        public $belongsTo = array(
            'document' => array(
                'className' => 'document',
                'foreignKey' => 'document_id'
                ));

        public $hasMany = array(
            'document_item_description' => array(
                'className' => 'document_item_description',
                'foreignKey' => 'document_item_id'
                ));
    }

    class DocumentItemDescription extends AppModel {
        public $hasOne = array(
            'document_item' => array(
                'className' => 'document_item',
                'foreignKey' => 'document_item_id'

                ));
    }

In my controller I'm using:

 public function index(){
    $res = $this->Document->find('all', array('recursive' => 3));
}

2条回答
倾城 Initia
2楼-- · 2019-08-19 07:02

I figured it out. I had all my models in an Api plugin. I needed to make my DocumentItemDescription association in my model like this:

    public $hasMany = array(
    'DocumentItem' => array(
        'className' => 'Api.DocumentItem',
        'foreignKey' => 'document_id'
    )
    );

For whatever reason I thought if my document model was within my plugin, it would find the rest which is not the case.

查看更多
趁早两清
3楼-- · 2019-08-19 07:09

Your question title pretty much answers your own question. You should use Containable behavior and not the recursive option. The recursive options has been removed from the new CakePHP 3, because it's very heavy on overhead and I would recommend you to avoid using it as much as you can. In order to get your 'deep' data, first add this to your Model files (or better yet, your AppModel, so you can always use it):

public $actsAs = array('Containable');

That will enable the containable behavior for your models. Then you can use the contain key in your find to join tables together, like this:

$this->Document->find('all', array(
    'contain' => array(
        'DocumentItem' => array(
            'DocumentItemDescription'
        )
    )
));

That will give you a data array with the related data as well. You can also filter which fields you want per Model by specifying a fields option inside any of the arrays.

查看更多
登录 后发表回答