2012-09-16 11 views
10

मैं केकपीएचपी 2.2.2 का उपयोग करता हूं मेरे पास 3 टेबल हैं: रेस्तरां, रसोई और रसोईघर_स्टेस्ट - एचएबीटीएम के लिए टेबल में शामिल हों।केकपीएचपी शर्तों के साथ एचएबीटीएम डेटा कैसे प्राप्त करें?

भोजनालय मॉडल में मेरे पास है:

public $hasAndBelongsToMany = array(
    'Kitchen' => 
     array(
      'className'    => 'Kitchen', 
      'joinTable'    => 'kitchens_restaurants', 
      'foreignKey'    => 'restaurant_id', 
      'associationForeignKey' => 'kitchen_id', 
      'unique'     => true, 
      'conditions'    => '', 
      'fields'     => 'kitchen', 
      'order'     => '', 
      'limit'     => '', 
      'offset'     => '', 
     ), 

समस्या यह है कि मैं अपने मुख्य पृष्ठ जिसमें मैं जटिल परिस्थितियों के साथ इस मॉडल से डेटा पुनः प्राप्त करने की आवश्यकता है के लिए अलग नियंत्रक है।

मैं अपने मुख्य पृष्ठ पर नियंत्रक को

public $uses = array('Restaurant'); 

जोड़ा गया है और यहाँ हिस्सा है जहां मैं अपने सलाह की जरूरत है आता है।

मुझे केवल उन रेस्तरां का चयन करने की आवश्यकता है जहां रसोई = $ आईडी। मैं

public function index() { 
$this->set('rests', $this->Restaurant->find('all', array(
'conditions' => array('Restaurant.active' => "1", 'Kitchen.id' => "1") 
))); 

} 

जोड़ने की कोशिश की है और मैं SQLSTATE [42S22] मिला: नहीं मिला कॉलम: 'जहां खंड' त्रुटि में 1054 अज्ञात स्तंभ। जाहिर है, मुझे "एचएबीटीएम जॉइन टेबल" से डेटा लाने की ज़रूरत है, लेकिन मुझे नहीं पता कि कैसे।

उत्तर

23

TLDR:

डेटा है कि एक [ HABTM ] के संघ के खिलाफ शर्तों के आधार पर सीमित है पुनः प्राप्त करने के लिए आपको [ Joins ] उपयोग करने के लिए की जरूरत है।

स्पष्टीकरण:

कोड नीचे [ Fat Model/Skinny Controller ] मंत्र इस प्रकार है, इसलिए तर्क ज्यादातर सभी मॉडल में है, और सिर्फ एक नियंत्रक से बुलाया जाता है।

नोट: यदि आप [ CakePHP conventions ] (जो यह दिखाई देता है) का पालन करते हैं तो आपको उन सभी HABTM पैरामीटर की आवश्यकता नहीं है।

नीचे दिए गए कोड का परीक्षण नहीं किया गया है (मैंने इसे इस साइट पर लिखा है), लेकिन यह बहुत साफ होना चाहिए और कम से कम आपको सही दिशा में ले जाना चाहिए।

कोड:

// भोजनालय मॉडल

public $hasAndBelongsToMany = array('Kitchen'); 

/** 
* Returns an array of restaurants based on a kitchen id 
* @param string $kitchenId - the id of a kitchen 
* @return array of restaurants 
*/ 
public function getRestaurantsByKitchenId($kitchenId = null) { 
    if(empty($kitchenId)) return false; 
    $restaurants = $this->find('all', array(
     'joins' => array(
      array('table' => 'kitchens_restaurants', 
       'alias' => 'KitchensRestaurant', 
       'type' => 'INNER', 
       'conditions' => array(
        'KitchensRestaurant.kitchen_id' => $kitchenId, 
        'KitchensRestaurant.restaurant_id = Restaurant.id' 
       ) 
      ) 
     ), 
     'group' => 'Restaurant.id' 
    )); 
    return $restaurants; 
} 

// किसी भी नियंत्रक

public function whateverAction($kitchenId) { 
    $this->loadModel('Restaurant'); //don't need this line if in RestaurantsController 
    $restaurants = $this->Restaurant->getRestaurantsByKitchenId($kitchenId); 
    $this->set('restaurants', $restaurants); 
} 
+1

डेव, धन्यवाद। आपका कोड बहुत अच्छी तरह से काम करता है। एक छोटा सा सवाल - क्या केवल उन फ़ील्ड का चयन करना संभव है जो मैं चाहता हूं (उदा। मुझे केवल कंपनी का नाम चाहिए, और कुछ अन्य जानकारी, सभी फ़ील्ड नहीं)? मैंने फ़ंक्शन getRestaurantsByKitchenId (रेस्टोरेंट मॉडल में) में 'फ़ील्ड्स' => सरणी ('Restaurant.companyname') जोड़ने का प्रयास किया है, लेकिन इससे कोई प्रभाव नहीं पड़ता है। – user1327

+0

@ user1327 - मदद करने के लिए खुशी हुई। हां, आपको मॉडल फ़ील्ड में 'फ़ील्ड्स' => सरणी() जोड़ने में सक्षम होना चाहिए। बस इसे 'जुड़ें' (भीतर नहीं) के समान स्तर पर रखें। आप आसानी से यह देखने के लिए डीबगकिट का उपयोग कर सकते हैं कि कौन से प्रश्न चल रहे हैं, और उस पर आधारित ट्विक कर सकते हैं। – Dave

+0

ओह, मुझे मूर्खतापूर्ण। अब सबकुछ काम करता है जैसा मैं चाहता हूं। एक बार फिर आपका धन्यवाद। – user1327

1

क्योंकि उपयोग की स्थापना की है, जिसका उपयोग आप [में शामिल होने के] की जरूरत नहीं कर सकते [HABTM] एसोसिएशन
रसोई मॉडल में एंडबेलॉन्ग टॉनी रेस्तरां मॉडल है ताकि आपके रूप में कोड कर सकें

KitchensControllers 
<?php 
    public function index() { 
    $this->Kitchen->recursive = 0; 
    $kitchens = $this->Kitchen->find('all', array('contain' => array('Restaurant'))); 
    $this->set('kitchens', $kitchens); 
    } 
?> 

शुभकामनाएँ!

+1

यह नहीं सभी रसोई घर वापस करो? – tsukimi

+0

हां, मुझे लगता है कि यह सभी रसोई घर लौटाएगा। हालांकि, कोड मॉडल ए में सभी रिकॉर्ड्स खोजने और मॉडल बी – Joseph

+0

से संबंधित एचएबीटीएम रिकॉर्ड दिखाने के लिए कोड सही है, यदि आप उन परिस्थितियों को ढूंढना चाहते हैं जो आप नमूना के रूप में उपयोग कर सकते हैं: $ -> रसोई-> ढूंढें ('सभी', सरणी ('स्थितियां' => सरणी ('kitchen.आईडी>' => '5'), 'युक्त' => सरणी ('रेस्तरां'))) –

1

डेव द्वारा प्रदान किए गए समाधान की तुलना में एक बहुत साफ तरीका है।

सबसे पहले आप की जरूरत के बीच रेस्तरां और एक रिवर्स HABTM रिश्ता स्थापित करने के लिए रसोईरसोई मॉडल में।

से तुम सिर्फ एक रसोई आप में रुचि रखते हैं (आईडी = 1) के लिए लगता है बनाने के लिए और आप जुड़े रेस्तरां मिल जाएगा, रेस्तरां क्षेत्रों के आधार पर फ़िल्टर के लिए Containable Behavior का उपयोग कर।

$this->Restaurant->Kitchen->Behaviors->attach('containable'); // Enable Containable for Kitchen Model 

$this->Restaurant->Kitchen->find('first', array(
    'recursive' => -1 // don't collect other data associated to Kitchen for performance purpose 
    'conditions' => array('Kitchen.id' => 1), 
    'contain' => array('Restaurant.active = 1') 
)); 

Source

संबंधित मुद्दे