CakePHP tek bir yabancı anahtar yok modelleri ile Çalışma

2 Cevap php

Ben bir yabancı (ve tamamen değişmez) kaynağından alınan verileri olan bir uygulama üzerinde çalışıyorum. Ben sorunu açıklamak için bazı tabloların basitleştirmek olacak. Aşağıda onların birincil anahtarlar ile tablolardır.

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)

Yani Faturalar, Başlıkları ve Teslimatlar One-to-One ilişkileri olduğunu görebilirsiniz. Faturalar-İşlemler-ve Faturalar-to-iletileri One-çok vardır.

Benim kendi veritabanına bu tabloları ithal, ben bir benzersiz anahtar olarak varolan bir birincil anahtar değiştirdim ve her masada (id) bir auto_incrementing alan eklendi.

Gerçekten de tüm kompozit tuşları işlemez beri Şimdi sorun, Kek ilişkiler kuruyor. Ben bu gibi çalışan One-to-One ilişkileri almak mümkün oldum:

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

Bire bir ilişkilerde büyük bir SOL JOIN ile tek seferde sorgulanan çünkü bu, çalışıyor. Tüm eşleşen Faturalar bulmak için ilk ve daha sonra ikinci bir gelen yabancı tüm İşlemler bulmak için: (Faturalar ve İşlemler ile örneğin) bir-çok ilişkisi ile aynı yöntemi deneyerek Kek iki sorgu yapar, çünkü, ölür İlk sorgudan sonuç eşleşen anahtar: (burada çalıştırmak için çalışıyor basitleştirilmiş sorgu)

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`

Sen sorgu ölür böylece faturalar üzerine katılarak değil, görebiliyorum.

Ben bu işi yapmak nasıl hakkında herhangi bir fikir?

2 Cevap

En kötü durum senaryosu, sen hasMany relationship in finderQuery parametresini kullanabilirsiniz. Bu tamamen sorguları geçersiz kılmak için izin verir.

Ayrıca içine ilgili veri alanlarını birleştiren benzersiz bir kimliği alanı eklemek mümkün olabilir. Bir UPDATE deyimi varolan verileri düzeltmek ve bir TETİK onlar eklenen veya değiştirilen yeni kayıtları güncellemek için ayarlanmış olabilir, veritabanı tetikler destekler varsayarak.

Edit: diğer tüm karmaşıklığı ile, () tamamen hasMany ilişkiyi atlama ve ayrı bulmak içinde İşlem kayıtları getiriliyor daha iyi olabilir. Bunu her zaman bu gibi Fatura modelinde bir fonksiyon içine olabilecek pek çok yerde yapmak varsa:

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

Eğer modelde böyle bir işlevi kullanırsanız, doğrudan kullanmak bile $ this-> İşlem tanımlanır böylece Fatura, İşlem için tanımlanmış bir ilişki gerekir unutmayın.

Ayrıca, bir hasMany ilişki olacağını şekilde iade edilecek veriler tercih ederseniz, her zaman bu şekilde onları tekrar birleşmek için foreach döngüsü ekleyebilirsiniz.

Update There's also a SimpleResults behavior in the Cake Bakery that would allow easily returning those results from the other table in the format of a regular hasMany association.