Bonjour, je cherche a afficher une liste de produits associé à plusieurs catégories.
Actuellement :
CategoriesTable.php
$this->belongsToMany('Products', [
'foreignKey' => 'category_id',
'targetForeignKey' => 'product_id',
'joinTable' => 'categories_products'
]);
ProdtuctsTable.php
$this->belongsToMany('Categories', [
'foreignKey' => 'product_id',
'targetForeignKey' => 'category_id',
'joinTable' => 'categories_products'
]);
Tables SQL
categories
categories_products
products
debug d'un produit
(int) 0 => object(App\Model\Entity\Product) {
'id' => (int) 15,
'name' => 'Nom du Produit',
'description' => 'Description du produit ',
'price' => (float) 0,
'ref' => '',
'living_space' => null,
'opening_space' => null,
'nb_room' => null,
'categories' => [
(int) 0 => object(App\Model\Entity\Category) {
'id' => (int) 30,
'name' => 'catégorie 1',
'description' => '',
'order' => (int) 0,
'parent_id' => null,
'lft' => (int) 3,
'rght' => (int) 4,
'_joinData' => object(Cake\ORM\Entity) {
'category_id' => (int) 30,
'id' => (int) 43,
'product_id' => (int) 15,
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'CategoriesProducts'
},
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Categories'
},
(int) 1 => object(App\Model\Entity\Category) {
'id' => (int) 33,
'name' => 'catégorie 2',
'description' => '',
'order' => (int) 1,
'parent_id' => null,
'lft' => (int) 7,
'rght' => (int) 8,
'_joinData' => object(Cake\ORM\Entity) {
'category_id' => (int) 33,
'id' => (int) 44,
'product_id' => (int) 15,
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'CategoriesProducts'
},
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Categories'
},
(int) 2 => object(App\Model\Entity\Category) {
'id' => (int) 37,
'name' => 'catégorie 3',
'description' => '',
'order' => (int) 2,
'parent_id' => null,
'lft' => (int) 17,
'rght' => (int) 18,
'_joinData' => object(Cake\ORM\Entity) {
'category_id' => (int) 37,
'id' => (int) 45,
'product_id' => (int) 15,
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'CategoriesProducts'
},
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Categories'
},
[...]
],
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Products'
},
(Le produit a bien N catégories)
Je ne sais pas comment effectuer une requête sur plusieurs categories_id
ex :
$products = $this->Products->find('all', [
'contain' => [
'Categories' => [
'conditions' => [
'Categories.id' => $data[0]['category_id'].','.$data[1]['category_id'].','.$data[2]['category_id'].','.$data[3]['category_id'],
]
]
]
]);
Si vous avez une piste pour filter les produits avec en paramètre un nombre N de catégories je prend
Merci
Salut, Xeta, merci pour ta réponse, cependant je n'arrive toujours pas a afficher uniquement les produits qui sont dans la sommes des 4 catégories , ma requête est probablement fausse :
$category_ids = [
$data[0]['category_id'],
$data[1]['category_id'],
$data[2]['category_id'],
$data[3]['category_id']
];
$products = $this->Products->find('all', [
'contain' => [
'Categories' => [
'conditions' => [
'Categories.id IN' => $category_ids,
]
]
]
]);
As tu la possibilité de m'aiguiller pour faire proprement cette requête ?
Merci
Hello,
Il te faut une clause IN si tu veux le faire sur plusieurs catégories.
http://book.cakephp.org/3.0/en/orm/query-builder.html#automatically-creating-in-clauses
Tu es sûr que ceci $data[3]['category_id'] affiche bien l'id de la catégorie ? Car sa parait bizarre d'utiliser une typographie de type array alors que les résultats sont des entities.
Yep! :)
$data[3]['category_id']
c'est juste un tableau fait à la main pour les tests
[...]
FROM
`categories` `Categories`
INNER JOIN `categories_products` `CategoriesProducts` ON `Categories`.`id` = (
`CategoriesProducts`.`category_id`
)
WHERE
(
`Categories`.`id` in (29, 33, 35, 42)
AND `CategoriesProducts`.`product_id` in (
'8', '9', '10', '11', '12', '13', '14',
'15', '16', '17', '18', '19', '20',
'21', '22', '23', '24', '25', '26',
'27', '28', '29'
)
)
Et ceci ?
$products = $this->Products
->find()
->contain([
'Categories'
])
->where([
'Categories.id IN' => $category_ids
]);
Nop!
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Categories.id' in 'where clause'
Config:
Tables SQL
categories
categories_products
`products``
CategoriesTable.php
$this->belongsToMany('Products', [
'foreignKey' => 'category_id',
'targetForeignKey' => 'product_id',
'joinTable' => 'categories_products'
]);
ProdtuctsTable.php
$this->belongsToMany('Categories', [
'foreignKey' => 'product_id',
'targetForeignKey' => 'category_id',
'joinTable' => 'categories_products'
]);
C'est ce qui me semble étonnant
Ah mais j'avais mal vue, il faut faire ta requête sur la table de jointure categories_products.
Quel est la structure de cette table ?
categories_products
CREATE TABLE `categories_products` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`category_id` int(11) DEFAULT NULL,
`product_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
Par contre je n'ai pas créé de model pour cette table je dois en créer un ?
Non pas besoin en faite.
Test voir ceci :
$products = $this->Products->find();
$products->matching('Categories', function ($q) use ($category_ids) {
return $q->where(['Categories.id IN' => $category_ids]);
});
Nop toujours pas ! Merci pour ton aide,
là pour le coups la requête m'affiche la totalité des produits..
Je sèche complètement