Pregunta

Estoy trabajando en una aplicación que tiene datos importados de una fuente extranjera (y totalmente inmutable). Simplificaré algunas de las tablas para explicar el problema. A continuación se muestran las tablas con sus claves principales.

invoices     (doc_number, date_printed, batch_number)
headers      (doc_number, date_printed, batch_number)
deliveries   (doc_number, date_printed, batch_number)
transactions (doc_number, date_printed, batch_number, line_number)
messages     (doc_number, date_printed, batch_number, line_number)

Para que pueda ver que las facturas, los encabezados y las entregas tienen relaciones uno a uno. Facturas a transacciones y Facturas a mensajes son uno a muchos.

Al importar estas tablas a mi propia base de datos, cambié la clave primaria existente para que sea una clave única y agregué un campo de aumento automático ( id ) en cada tabla.

Ahora el problema es configurar las relaciones en Cake, ya que realmente no maneja las teclas compuestas en absoluto. Pude lograr que las relaciones uno a uno funcionen así:

class Invoice extends AppModel {
    public $name = "Invoice"
         , $hasOne = array(
            "Header" => array(
                'foreignKey' => false,
                'conditions' => array(
                    "Invoice.doc_number = Header.doc_number",
                    "Invoice.date_printed = Header.date_printed",
                    "Invoice.batch_number = Header.batch_number"
                )
            )
         )
    ;
}

Y esto funciona, porque las relaciones uno a uno se consultan de una vez con una gran IZQUIERDA. Intentar el mismo método con una relación de uno a muchos (por ejemplo, con Facturas y Transacciones) muere, porque Cake hace dos consultas: la primera para encontrar todas las Facturas coincidentes y luego la segunda para encontrar todas las Transacciones con un correspondiente extranjero clave que coincide con los resultados de la primera consulta: (aquí está la consulta simplificada que está tratando de ejecutar)

SELECT `Transaction`.* FROM `transactions` AS `Transaction`
WHERE `Invoice`.`doc_number` = `Transaction`.`doc_number`
AND `Invoice`.`date_printed` = `Transaction`.`date_printed`
AND `Invoice`.`batch_number` = `Transaction`.`batch_number`

Puede ver que no se une a las facturas, por lo que la consulta muere.

¿Alguna idea sobre cómo puedo hacer que esto funcione?

¿Fue útil?

Solución

En el peor de los casos, puede usar el parámetro finderQuery de la relación hasMany . Le permite anular completamente las consultas.

También puede agregar un campo de identificación único que combine los campos de datos relevantes en uno. Una instrucción UPDATE podría corregir los datos existentes y se podría configurar un GATILLO para actualizar nuevos registros a medida que se agregan o cambian, suponiendo que su base de datos admita disparadores.

Editar: con todas las otras complejidades, es mejor que omita la relación hasMany por completo y obtenga los registros de Transacción en un hallazgo separado (). Si tiene que hacerlo en muchos lugares, siempre puede envolverlo en una función en el modelo de Factura como este:

<?php
class Invoice extends AppModel() {
    ...

    function getInvoice($conditions) {
        $invoice = $this->find('first', compact('conditions'));

        $conditions = array(
             'Transaction.doc_number' => $invoice['Invoice']['doc_number'],
             'Transaction.date_printed' => $invoice['Invoice']['date_printed'],
             'Transaction.batch_number' => $invoice['Invoice']['batch_number']);
        $invoice['transactions'] = $this->Transaction->find('all', compact('conditions'));

        return $invoice;
    }
}
?>

Si usa una función como esa en el modelo, no olvide que Factura necesitaría una relación definida con Transaction, incluso si no la usa directamente, de modo que $ this- > Transaction está definida.

Además, si prefiere que los datos se devuelvan como lo haría una relación hasMany, siempre puede agregar un bucle foreach para recombinarlos de esa manera.

Actualizar También hay un Comportamiento SimpleResults en Cake Bakery que permitiría devolver fácilmente esos resultados de la otra tabla en el formato de una asociación hasMany regular.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top