Pablushka
Pablushka

Reputation: 103

CakePHP: HABTM and Recursive attribute to get all related data

I'm in trouble with HABTM relationship in my model. I searched for examples and references on this site and many others for a couple of weeks without success. The clasical Posts HABTM Tags official documentation works well but extrapolated to my model fails. All information found does not contain examples or references for composite primary keys (I suspect the relationship will not work because of the composite primary keys and I can`t change this schema)

My goal is to get the Relationship:

 Customer HABTM Products.

So, with

$customers = $this->Customer->find('all');

Get the array of all products related to a customer in the Customer object .

Currently I can´t get this to work: $customer does not have the spected Products array.

I appreciate any help or reference to help me fix this.

This is my db:

CREATE TABLE `customers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `lang` varchar(2) NOT NULL,
  `name` varchar(145) NOT NULL,
  `logo` varchar(145) NOT NULL,
  `description` text,
  PRIMARY KEY (`id`,`lang`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8

CREATE TABLE `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `lang` varchar(2) NOT NULL,
  `category_id` int(11) NOT NULL,
  `service_id` int(11) NOT NULL,
  `description` text,
  `picture` varchar(145) NOT NULL,
  PRIMARY KEY (`id`,`category_id`,`service_id`,`lang`),
  KEY `fk_products_services1` (`service_id`,`lang`),
  KEY `fk_products_categories1` (`category_id`,`lang`),
  CONSTRAINT `fk_products_categories1` FOREIGN KEY (`category_id`, `lang`) REFERENCES `categories` (`id`, `lang`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `fk_products_services1` FOREIGN KEY (`service_id`, `lang`) REFERENCES `services` (`id`, `lang`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8


CREATE TABLE `customer_products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `customer_id` int(11) NOT NULL,
  `product_id` int(11) NOT NULL,
   PRIMARY KEY (`id`,`customer_id`,`product_id`),
   KEY `fk_customer_products_products1` (`product_id`),
   KEY `fk_customer_products_customers` (`customer_id`),
   CONSTRAINT `fk_customer_products_customers` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
   CONSTRAINT `fk_customer_products_products1` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

This is my Customer model:

<?php
App::uses('AppModel', 'Model');
/**
 * Customer Model
 *
 * @property CustomerProduct $CustomerProduct
 * @property Product $AllProducts
 */
class Customer extends AppModel {
/**
 * Display field
 *
 * @var string
 */
    public $displayField = 'name';

    //The Associations below have been created with all possible keys, those that are not needed can be removed


/**
 * hasAndBelongsToMany associations
 *
 * @var array
 */
    public $hasAndBelongsToMany = array(
        'Products' => array(
            'className' => 'Product',
            'joinTable' => 'customer_products',
            'foreignKey' => 'customer_id',
            'associationForeignKey' => 'product_id',
            'unique' => true,
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'finderQuery' => '',
            'deleteQuery' => '',
            'insertQuery' => ''
        )
    );

}

This is my index Customer controller method:

public function index() {
    $this->layout = 'header_chico';
    $this->Customer->recursive = 0;
    $customers = $this->Customer->find('all');
    $this->set('customers', $customers);
}

Upvotes: 1

Views: 1198

Answers (1)

Chuck Burgess
Chuck Burgess

Reputation: 11574

Your HABTM table should be customers_products (not customer_products). That will probably fix it. Remember the format is both plural in alphabetical order. So if it's customers HABTM products it is customers_products. If it were users HABTM products it would be products_users.

UPDATE

If you want the HABTM records to appear in the index, you also need to remove:

$this->Customer->recursive = 0;

This will prevent related records from appearing.

Upvotes: 1

Related Questions