Bir koleksiyon sorgusu üzerine bir tabloyu sola katılın


27

İhracat için sistemden bazı siparişler almak için aşağıdakileri yapıyorum:

$orders = Mage::getModel('sales/order')->getCollection()
    ->addFieldToFilter('status', $statusToExport)
    ->addFieldToFilter('store_id', $this->processingStoreId)
    ->addFieldToFilter('updated_at', array('gteq' => date('Y-m-d H:i:s', $lastSyncTime)));

Ben nerede bir şey eklemem gerekiyor gelmez sipariş eğer dışa entity_idBen özel bir tablodur. SQL kullanıyor olsaydım, yapardım:

left join myTable as mt on main_table.entity_id = mt.entity_id
where mt.entity_id is null

Ancak benzer bir şeyi yapmak için toplama sorgusunu nasıl değiştireceğimi bilmiyorum.

Not: Denedim

$orders = $orders->getSelect()
    ->joinLeft(
        array("t1" => $myTable),
        "main_table.entity_id = t1.entity_id",
        array("admin_field_id" => "t1.id")
    )
    ->where("t1.id is null")

ama bu onu değiştirir, böylece bir sorgu olur ve satış / sipariş tahsilatının iade edilmesini istiyorum

Basit bir şey kaçırdığımı hissediyorum ...

DÜZENLE

Tamam, bunu denedim:

$orders->getSelect()
    ->joinLeft(
        array("t1" => $myTable),
        "main_table.entity_id = t1.entity_id",
        array("admin_field_id" => "t1.id")
    )
    ->where("t1.id is null");

Yankı (string)$orders->getSelect(), sorguyu döndürür ve beklediğimde çalıştırdığımda sonuç döndürmez. $ordersancak yine de öğeler içeriyor. Bu birleşimin bu noktada koleksiyonunu değiştirmesi gerektiğini düşündüm?

Yanıtlar:


53

Sorguyu değiştirmek için yapabileceğiniz

$collection->getSelect()->doWhateverYouWantWithSelectObject();
foreach($collection as $order) {} // order collection

Ama bir masaya katılmak için, sadece kullanabilirsiniz $collection->joinTable()

joinTablesadece Mage_Eav_Model_Entity_Collection'da var, bunun anlamı: ürünler, kategoriler, siparişler, faturalar, creditmemo, nakliye, müşteriler. (Yorumunuz için teşekkürler @Fra)

joinTable ()

Ancak magento koleksiyonlarının joinTable()nasıl kullanıldığını ortaya çıkarmak için bana 45 dakika süren bir yöntemi var . Bunu senin için önlemek için paylaşıyorum.

$productCollection->joinTable(
    array('bonus' => 'mycompany/bonus'), 'product_id=entity_id',
    array('bonus_id' => 'bonus_id')
);

Parametreler:

public function joinTable($table, $bind, $fields = null, $cond = null, $joinType = 'inner')
  1. Tablo kolaydır, namespace/entityyapılandırmanızda, kaynak modellerinde ve koleksiyonunda kullandığınız magento formatıdır. Bir format dizisini kullanabilirsinizarray('alias' => 'namespace/entity')
  2. Bağlama, SQL'inizdeki ON ifadesi anlamına gelir. Bu en zor kısımdı ve daha sonra detaylı olarak açıklayacağım. Eşit tablonun SONRA düz masanızın ve EAV masanızın olması önemlidir. Özellikten main_table.önce kullanmayın . Magento bunu senin için yapacak. Bunun üzerine daha sonra.
  3. Alanlar bir dizidir . Bunun yerine bir dize kullanırsanız, bu olsun: Warning: Invalid argument supplied for foreach() in /var/www/magento-1.6.2.0/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php on line 775. Biçimin bir dizisini kullanabilirsiniz array('field1', 'field2', '...')veyaarray('alias' => 'field1', '...')
  4. Durum bir ** NEREDE AÇIK koşulu ** SQL'de.
  5. joinType. Umarım ne olduğunu biliyorsundur. Fakat sadece SOL ve İÇEREN arasında seçim şansınız var .app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php:793

Bu konuda daha fazlası


1
Bu harika bilgi için teşekkürler. İlk noktanıza göre, $orders->getSelect() ->joinLeft(array("t1" => $myTable), "main_table.entity_id = t1.entity_id", array("admin_field_id" => "t1.id")) ->where("t1.id is null")öğeleri mevcut listemden hariç tutmamalı mıyım?
webnoob

Yüklemeden sonra koleksiyonu düzenlediğinizi düşünüyorum. sadece betiğe xdebug ile bağlanın ve modelin içindeki isLoaded bayrağını kontrol edin
Fabian Blechschmidt

2
joinTable yönteminin yalnızca Mage_Eav_Model_Entity_Collection
Fra

1

Bunun nedenini buldum.

Sol birleştirmeyi uygulamadan önce bir miktar değer istedim , böylece ekledim

$totalOrderCount = count($orders);

Ancak bu, koleksiyonun yüklenmesine neden oldu, bu da daha sonra yaptığım sol birleşimi görmezden geliyordu. Hata ayıklama yaparken var'a bakmak _isCollectionLoadedFabian tarafından iyi bir ipucuydu.

Şimdi koleksiyonun sayısını almak için bunu yapıyorum:

$countOrdersObjs = clone $orders;
$totalOrderCount = count($countOrdersObjs);
unset($countOrdersObjs);

Bu, $orderstoplama yüklemeden sonuçları saymamı sağlar.

Not: Lütfen bu konuda bana rehberlik ettiği için yukarıdaki Fabians'a herhangi bir büyütme başvurusu yapın ancak çözümün kendi cevabını garantilediğini hissettim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.