2010-03-25 22 views
9

Estoy tratando de construir un sistema de navegación usando una tabla de categorías con jerarquías. Normalmente, la tabla se define como sigue:MySQL y PHP - Creando relaciones secundarias múltiples

id (int) - Primary key 
name (varchar) - Name of the Category 
parentid (int) - Parent ID of this Category referenced to same table (Self Join) 

Pero el problema es que yo requiero que una categoría puede ser niño a múltiples categorías padre .. Al igual que A tiene y pertenece a muchos relación (HABTM).

Sé que si hay dos tablas, categorías & elementos, utilizamos una tabla de unión categories_items para enumerar las relaciones HABTM. Pero aquí no estoy teniendo dos tablas sino solo una tabla, pero de alguna manera debería mostrar las relaciones HABTM consigo mismo. ¿Es esto posible usando una sola tabla? Si es así, ¿cómo? Si no es posible, ¿qué reglas (nomenclatura de tabla, campos) debo seguir al crear la tabla de combinación adicional?

Estoy tratando de lograr esto con CakePHP, si alguien puede proporcionar la solución de CakePHP para este problema, sería increíble. Incluso si eso no es posible, se agradece cualquier solución para crear una tabla de unión. Gracias por tu tiempo.

- Editar - Mi pregunta parece ser un poco confusa, así que estoy tratando de reformular lo que estoy buscando. En las relaciones tradicionales entre padres e hijos con autorreferencia (unión automática), cada elemento puede tener solo un padre. Lo que estoy buscando es simular una relación HABTM, es decir, múltiples padres para cada elemento.

Categorías & Elementos - Para definir HABTM, utilizamos categories_items join table.

Si dentro de las categorías necesito HABTM, ¿qué debo hacer?

+0

u puede guardar los valores múltiples en un campo por ellos separados por comas o algún separador –

+0

1 pregunta interesante :-) – richsage

+0

me encontré con esto mientras que buscando en Google, http://n2.nabble.com/Saving-self- referencial-HABTM-relationships-td1126141.html, he tratado de replicar lo mismo, pero aún así Cake no está captando la asociación. Alguna idea, alguien? – Ashok

Respuesta

0

¡Gracias por último.

Naviitems Tabla:

CREATE TABLE IF NOT EXISTS `naviitems` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(50) NOT NULL, 
    `linkurl` varchar(250) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

Auto tabla de unión:

CREATE TABLE IF NOT EXISTS `naviitems_parents` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `naviitem_id` int(11) NOT NULL, 
    `parent_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

Naviitems Modelo:

<?php 
class Naviitem extends AppModel { 

    var $name = 'Naviitem'; 

    //The Associations below have been created with all possible keys, those that are not needed can be removed 
    var $hasAndBelongsToMany = array(
     'Parent' => array(
      'className' => 'Naviitem', 
      'joinTable' => 'naviitems_parents', 
      'foreignKey' => 'naviitem_id', 
      'associationForeignKey' => 'parent_id', 
      'unique' => true, 
      'conditions' => '', 
      'fields' => '', 
      'order' => '', 
      'limit' => '', 
      'offset' => '', 
      'finderQuery' => '', 
      'deleteQuery' => '', 
      'insertQuery' => '' 
     ) 
    ); 
} 
?> 

he generado el controlador y el uso de la cáscara Vistas bake. Está funcionando bien ahora. Gracias por todas las ideas que has contribuido, me han ayudado mucho.

0

Lo que está tratando de lograr no es realmente un enfoque Cake. Debería utilizar dos tablas con una tabla de unión entre. La máxima de Cake es 'convención sobre configuración', por lo que deberías usar la forma estándar de pastel.

Para crear la HABTM, querrá tres tablas.

items 
categories 
categories_items 

El artículo y la categoría son como usted espera. Su tabla de unión solo debe contener los dos identificadores de las tablas combinadas de la siguiente manera,

category_id 
item_id 

Esto le permitirá tener un elemento de navegación aparezca en varias categorías, en caso de que así lo desea.

Más información se puede encontrar en el libro, http://book.cakephp.org/view/1044/hasAndBelongsToMany-HABTM

+0

Heads-up: Ashok no tiene dos tablas, pero una que se refiere a sí misma. :) – pinkgothic

+0

Este es el 'camino de la torta' según lo solicitado en la pregunta :) –

+0

Has malentendido mi pregunta ... No estoy tratando de crear un HABTM entre categorías y artículos ... Estoy tratando de crear un HABTM dentro de Tabla de categorías. – Ashok

2

tratar de exprimir un n: m relación (HABTM) en una relación 1: n no es una buena práctica y se encontrará con limitaciones que no lo haría si lo hizo limpiamente, pero así es como podría hacerlo (PHP genérico, no específico de CakePHP):

Puede crear una columna en su tabla para almacenar todas las ID principales en una lista separada por comas. Usted puede leer las identificaciones individuales a cabo mediante el uso de ...

$ids = explode(',', $idsFromColumn); 

... y escribir de nuevo en la columna usando ...

$idsForColumn = implode(',', $ids); 

real de lectura y escritura de la base de datos podría suceder antes/después de esos fragmentos, respectivamente.


Si quieres hacerlo bien, que desea que la tabla principal para tener este aspecto:

id (int) - Primary key 
name (varchar) - Name of the Category 

Y tu n: m relación de tabla para que parezca esto:

id (int) - child 
parentid (int) - parent 

Lo preguntaría de esta manera:

SELECT ... 
FROM 
    main_table AS m 
    [LEFT OUTER|INNER] JOIN 
    relationship_table AS r 
     ON r.id=m.id 
    [LEFT OUTER|INNER] JOIN 
    main_table AS n 
     ON r.parentid=n.id 
WHERE ... 

Exactamente lo que quiere en usted DONDE y su SELECCIONE será lo que espera lograr. En cuanto a si desea UNIÓN EXTERIOR IZQUIERDA o ÚNICO ÚNASE, eso depende de si desea devolver categorías en m. * Que no tienen una entrada en su tabla de relación (= no tiene ningún elemento primario). Si es la primera vez que se une a la sintaxis, consulte this Wiki article on joins.

+0

Gracias, esto fue útil. – Ashok

1

Esto es casi exactamente para lo que está diseñado el Tree behaviour. El comportamiento se basa en MPTT (Modified Preorder Tree Traversal). Entonces configuraría así:

Añadir los siguientes campos a la tabla:

`parent_id` int(10) unsigned default NULL 
`lft` int(10) unsigned default NULL 
`rght` int(10) unsigned default NULL 

Modelo:

class Category extends AppModel 
{ 
    var $actsAs = array('Tree'); 
} 

A continuación, harías con un parent_id <select> en sus formas de modificación de la categoría, y el comportamiento del árbol se ocuparía del resto. Supongo que puede manejar manualmente el reordenamiento de las categorías dentro de un nivel de su jerarquía de categorías, pero probablemente sea mejor que use los métodos moveUp y moveDown disponibles en modelos extendidos con el comportamiento de árbol.

Aquí, también, es útil Tree Helper para convertir las listas de árbol en listas ordenadas/desordenadas en sus vistas.

+1

Hola, pero incluso el comportamiento de Tree no maneja las relaciones HABTM de múltiples elementos primarios. En el enlace que proporcionó, http://book.cakephp.org/view/91/Tree, como puede ver, cada categoría puede ser una subcategoría solo una vez ... En otras palabras, cada categoría puede tener solo un padre. Lo que estoy buscando son padres múltiples para cada categoría ... – Ashok

+0

Oof, te he malinterpretado. Mis disculpas. –

3

Espero que no esté mal la forma de responder una segunda vez, habiendo malentendido la pregunta la primera vez. La siguiente es esencialmente una implementación de CakePHP de pinkgothic's answer.

Nueva HABTM tabla de unión:

CREATE TABLE `categories_parent_categories` (
    `category_id` int(10) unsigned NOT NULL, 
    `parent_category_id` int(10) unsigned default NULL, 
    `order` int(10) unsigned NOT NULL default '0' 
); 

Asociación de modelo:

class Category extends AppModel 
{ 
    var $hasAndBelongsToMany = array(
     'ParentCategory' => array(
      'className'    => 'Category', 
      'joinTable'    => 'categories_parent_categories', 
      'foreignKey'   => 'category_id', 
      'associationForeignKey' => 'parent_category_id', 
      'order'     => 'CategoriesParentCategory.order' 
     ) 
    ); 
} 
+0

Hola, gracias por intentar ayudarme, pero me temo que el código no funcionó. Cake no captó la asociación. Al agregar un artículo, no se muestra la opción para seleccionar un ID padre. – Ashok

+0

Gracias por la entrada de Hobonium, pude obtener la solución mediante algunas modificaciones de su código. Lo publiqué aquí. – Ashok