I’m trying to traverse the relations on CakePHP models.
This is the database:
I can access product attributes (product->attributes
) on a product model but I cannot access the product attributes on Ad model (ad->product->attributes
).
Here is my code:
//Product Model
class Product extends AppModel {
public $useTable = 'products';
public $displayField = 'name';
public $hasAndBelongsToMany = array(
'Attributes' =>
array(
'className' => 'Attribute',
'joinTable' => 'product_has_attributes',
'foreignKey' => 'products_id',
'associationForeignKey' => 'attributes_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'with' => 'product_has_attributes'
)
);
public $hasMany = array(
'Ads' => array(
'className' => 'Ad',
'foreignKey' => 'Products_id',
'conditions' => '',
'order' => '',
'limit' => '',
'dependent' => true
)
);
//Ad Model
class Ad extends AppModel {
public $displayField = 'Name';
public $belongsTo = array(
'Product' => array(
'className' => 'Products',
'foreignKey' => 'products_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
//Attribute Model
class Attribute extends AppModel {
public $displayField = 'name';
public $hasAndBelongsToMany = array(
'Products' =>
array(
'className' => 'Product',
'joinTable' => 'product_has_attributes',
'foreignKey' => 'attributes_id',
'associationForeignKey' => 'products_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'with' => 'product_has_attributes'
)
);
// Products controller -> Action View
class ProductsController extends AppController {
public function view($id = null) {
if (!$this->Product->exists($id)) {
throw new NotFoundException(__('Invalid product'));
}
$options = array('conditions' => array('Product.' . $this->Product->primaryKey => $id));
$this->set('product', $this->Product->find('first', $options));
}
}
// Ads controller -> Action View
class AdsController extends AppController {
public function view($id = null) {
if (!$this->Ad->exists($id)) {
throw new NotFoundException(__('Invalid ad'));
}
$options = array('conditions' => array('Ad.' . $this->Ad->primaryKey => $id));
$this->set('ad', $this->Ad->find('first', $options));
}
And here is what I do in the views:
//Products Views: snipet of view.ctp
print_r ($product);
// this prints rhe product and all associated attributes
//Ads Views: snipet of view.ctp
print_r ($ad['Product']);
//this will print only the product fields, but not the attributes associated to the product
What is wrong? How do I access the relation Ad->product->attribute
from my Ad model?
Advertisement
Answer
Perhaps the problem could be that you’re not using CakePHP’s conventions.
From the docs:
“new join table’s name needs to include the names of both models involved, in alphabetical order, and separated with an underscore ( _ ).”
So, your join table should be named attributes_products
.
Also, check your foreign keys. They should be in singular form.
- attributes_products.id
- attributes_products.product_id
- attributes_products.attribute_id
Hopefully that solves the problem.
References: