Pergunta

Eu estou trabalhando em um aplicativo que tem dados importados de uma fonte externa (e totalmente imutável). Vou simplificar algumas das tabelas para explicar o problema. Abaixo estão as tabelas com as suas chaves primárias.

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)

Assim você pode ver que as facturas, cabeçalhos e entregas têm One-to-One relacionamentos. e faturas-to-Mensagens são um-para-muitos faturas Transações-to-.

Em importar essas tabelas para o meu próprio banco de dados, eu mudei a chave primária existente para ser uma chave única e adicionado um campo auto_incrementing (id) em cada tabela.

Agora o problema é a criação de relacionamentos em Cake, uma vez que não realmente lidar com chaves compostas em tudo. Eu tenho sido capaz de obter os relacionamentos um-para-um trabalho como este:

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"
                )
            )
         )
    ;
}

e isso funciona, porque os relacionamentos um-para-um são consultados de uma só vez com um grande LEFT JOIN. Tentando o mesmo método com uma relação de um-para-muitos (por exemplo, com facturas e transacções) fieiras, porque o bolo faz duas consultas: a primeira a encontrar todas as facturas de correspondência, e, em seguida, a segunda para pesquisar todas as transações com um correspondente estrangeira chave que coincide com os resultados da primeira consulta: (aqui está a consulta simplificada que está tentando executar)

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`

Você pode ver, não é entrar em faturas assim as matrizes de consulta.

Todas as idéias sobre como eu posso fazer este trabalho?

Foi útil?

Solução

pior cenário, você pode usar o parâmetro finderQuery do hasMany relação . Ele permite que você substituir completamente as consultas.

Você também pode ser capaz de adicionar um campo ID único que combina os campos de dados relevantes em um só. Uma instrução UPDATE poderia corrigir os dados existentes e um gatilho pode ser configurado para atualizar novos registros à medida que são adicionadas ou alteradas, assumindo que desencadeia seus apoios de banco de dados.

Editar: Com todas as outras complexidades, você pode ser melhor fora pular o relacionamento hasMany completamente e buscar os registros de transação em um achado separado (). Se você tiver que fazê-lo muito muitos lugares que você poderia sempre envolvê-la em uma função no modelo de fatura como esta:

<?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;
    }
}
?>

Se você usar uma função como essa no modelo, não se esqueça que fatura precisaria de uma relação definida a transação, mesmo se você não usá-lo diretamente, de modo que $ this-> Transaction está definida.

Além disso, se você preferir os dados a serem devolvidos a maneira um relacionamento hasMany seria, você pode sempre adicionar um loop foreach para recombinar-los dessa forma.

Atualizar Há também um SimpleResults comportamento no Bolo Padaria , que permitiria facilmente retornar esses resultados da outra tabela no formato de uma associação normal hasMany.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top