How do I traverse CakePHP relations?

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 ?


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:

    http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasandbelongstomany-habtm

    http://book.cakephp.org/2.0/en/getting-started/cakephp-conventions.html#model-and-database-conventions


    I can think of a couple of simple ways to accomplish this.

    First:

    class AdsController extends AppController {
        if (!$this->Ad->exists($id)) {
            throw new NotFoundException(__('Invalid ad'));
        }
        $options = array(
            'conditions' => array('Ad.' . $this->Ad->primaryKey => $id),
            'recursive' => 1, // or more
        );
        $this->set('ad', $this->Ad->find('first', $options));
    }
    

    That would be the simplest code change to make sure you get attributes that are related to the product that is returned.

    Otherwise, you alluded to this in your question. You can access related Models through the model, so:

    $this->Ad->Product->find(...);
    

    I have had issues with Cake not liking my find conditions when using related models in conditions, and I'm not sure of the proper syntax, but if you wanted to pursue that, I'm sure you can track it down through the docs or by experimentation.

    Finally, I would advise you to check into the ContainableBehavior, which will allow you to fine tune which fields are actually returned in the results. I hope this answers your question!

    链接地址: http://www.djcxy.com/p/64888.html

    上一篇: HasMany通过多个条目

    下一篇: 我如何遍历CakePHP关系?