2012-05-14 7 views
5

Estoy tratando de ponerme en forma con hasMany autorreferencial bidireccional a través de las relaciones en CakePHP (¡qué bocado!).CakePHP: auto-referencial bidireccional hasMany A través de asociaciones

Estoy trabajando en un sitio web que combine imágenes.

  • Las imágenes están asociadas a otras imágenes mediante una "coincidencia" (el modelo de unión).
  • Cada partido tiene dos imágenes y almacena la calificación actual y el número total de votos.
  • Al ver una imagen, todas sus imágenes relacionadas desde cualquier dirección deberían estar disponibles (a través de sus coincidencias).

Empecé definiendo una relación hasMany a través de un modelo de unión.

Los pictures_matches tabla de unión tiene esta estructura:

id | picture_id | partner_id | rating | total_votes 

de mi pareja integrarán asociación de modelo se parece a esto:

class PictureMatch extends AppModel { 

... 

    public $belongsTo = array(
     'Picture' => array(
      'className' => 'Picture', 
      'foreignKey' => 'picture_id', 
      'conditions' => '', 
      'fields' => '', 
      'order' => '' 
     ), 
     'Partner' => array(
      'className' => 'Picture', 
      'foreignKey' => 'partner_id', 
      'conditions' => '', 
      'fields' => '', 
      'order' => '' 
     ) 
    ); 
} 

Cada imagen tiene que ser capaz de acceder a sus imágenes relacionados de una u otra dirección, pero aquí es donde mi comprensión se desliza. Parece que necesito guardar ambos lados de la relación, pero esto destruye los datos adicionales almacenados en el modelo de unión: con dos entradas de base de datos, la votación podría variar según la dirección.

¿Alguien puede arrojar alguna luz sobre la mejor manera de hacer esto en CakePHP? Estoy bastante confundido.
¿Es posible crear relaciones inversas sobre la marcha?

+3

¿Alguna vez resolvió esto? –

+0

¿Debería className en la sección Partner ser 'Partner'? – khany

Respuesta

0

Puede crear realidades sobre la marcha vie Model :: bindModel(), algo muy útil que le permitirá ligar las relaciones inversas o más bien cualquier dirección que desee sobre la marcha.

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

También usando el comportamiento Containable puede crear cadena infinita de retriving su fecha ex asociado.

contienen ('Picture.PictureMatch.Partner.PictureMatch.Picture .....')

Básicamente se puede recorrer todos sus modelos, siempre y cuando cada cadena es de alguna manera relacionada con el siguiente para explicar que ejemplo más sencillo (no tenga en cuenta la lógica en ella)

Circle Square belongsTo Plaza belongsTo Triángulo

Así triángulo no está relacionado con círculo (directamente), pero la plaza es un poco en el medio

Circle->find('all', array('...', contain => array('Square.Triangle')); 

o para tener más diversión deja para conseguir círculo en círculo con el lazo alrededor

Circle->find('all', array('...', contain => array('Square.Trinagle.Square.Circle')); 

y así sucesivamente, por supuesto, aquellos ejemplo son inútiles y sin ninguna lógica de programación, pero espero que entender el punto de que pueda bucle a través de un número infinito de relaciones que van y vienen.

0

No estoy seguro si esto es la mejor solución, pero si lo hizo esto:

public $belongsTo = array(
    'Picture1' => array(
     'className' => 'Picture', 
     'foreignKey' => 'picture_id', 
    ), 
    'Picture2' => array(
     'className' => 'Picture', 
     'foreignKey' => 'picture_id', 
    ), 
    'Partner' => array(
     'className' => 'Partner', 
     'foreignKey' => 'partner_id', 
    ), 
); 

entonces cuando se hace una búsqueda que sólo la búsqueda de ($this->data['Picture1'] == $var || $this->data['Picture2'] == $var) y así siempre y cuando tenga recursive puesto a 1 o 2 deberías recuperar todos los datos relacionados para ese Picture.

0

Asumo que esto es abandonado, pero es fácilmente resoluble - tiene que ver con la fase

destruye los datos adicionales almacenados en el modelo unirse a

Esto significa que su guarda se están ejecutando a deleteAll e insertando el registro en la coincidencia ... en su lugar necesita encontrar y actualizar ese registro ...

Esto se puede hacer de varias maneras, pero la más fácil es antes de su llamada a guardar, búsquelo y incluir el pri maria clave en los datos del registro del partido. Básicamente no lo guarde como HABTM, y solo guárdelo como hasMany si ya ha intentado encontrar una clave primaria de registro de coincidencia existente (id) y actualizó los datos para guardar con ella.

Cuestiones relacionadas