问题
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));
}
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/29442675/containable-and-deep-associated-data