2011-11-22 12 views
6

मैं केकपीएचपी में असंतुलित व्यवहार का उपयोग करने की कोशिश कर रहा हूं लेकिन मुझे उम्मीद है कि मैं इसे काम करने के लिए तैयार नहीं कर सकता।केकपीएचपी: बहुस्तरीय कंटेनबल व्यवहार का उपयोग

मेरा आवेदन अलग है, लेकिन सरल बनाने के लिए मैं यह उदाहरण डालूंगा। मान लें कि मेरे पास धागे और गतिविधियों के साथ एक मंच है, और गतिविधियों को रेट किया जा सकता है। सामान्य संबंधों होगा:

फोरम: hasMany [धागा]
थ्रेड: belongsTo [फोरम], hasMany [गतिविधि]
गतिविधि: belongsTo [धागा], hasMany [रेटिंग]
रेटिंग: belongsTo [गतिविधि]

जो मैं प्राप्त करना चाहता हूं वह है, ढूंढने के तरीके का उपयोग करके, एक निश्चित मंच पर सभी रेटिंग प्राप्त करें।

$this->Rating->find('count', array(
    'contain' => array(
     'Activity' => array(
      'Thread' 
     ) 
    ), 
    'conditions' => array(
     'Thread.forum_id' => 1 
    ) 
)); 

लेकिन परिणाम क्वेरी है: क्या मैं किया जाना चाहिए लगता है निम्नलिखित है

SELECT COUNT(*) AS `count` FROM `ratings` AS `Rating` LEFT JOIN `activities` AS `Activity` ON (`Rating`.`activity_id` = `Activity`.`id`) WHERE `Thread`.`forum_id` = 1; 

मैं इस 'मिलती है' विकल्प का उपयोग पूरा किया है, लेकिन यह अधिक जटिल है और मैं करने के लिए है कई स्थितियों में इस तरह की कार्रवाई का प्रयोग करें।

सभी उदाहरण के साथ संबंधित फाइलों यहां पाया जा सकता: http://dl.dropbox.com/u/3285746/StackOverflow-ContainableBehavior.rar

धन्यवाद

अद्यतन 23/11/2011

ढांचे और Moz मॉरिस का उत्तर देने के लिए धन्यवाद की जांच करने के बाद और api55 मुझे समस्या का स्रोत मिला।

मूल समस्या यह थी कि, जैसा कि मैंने केकेपीएचपी को समझा, मैंने सोचा कि यह हर बार जुड़ने का उपयोग कर पूछताछ कर रहा था। बात यह है कि यह है कि ऐसा नहीं है कि, वास्तविक ऑपरेशन में यह परिणाम मैं खोज रहा था प्राप्त करने के लिए प्रदर्शन करेंगे कुछ इस तरह होगा:

SELECT * FROM Rating JOIN Activity... 
SELECT * FROM Activity JOIN Thread... 
SELECT * FROM Activity JOIN Thread... 
... 

मतलब है कि यह एक प्रश्न करना होगा सभी गतिविधियों प्राप्त करने के लिए और फिर, प्रत्येक गतिविधि के लिए, थ्रेड प्राप्त करने के लिए एक क्वेरी करें ... मेरा दृष्टिकोण असफल व्यवहार का उपयोग गलत नहीं होने के कारण विफल रहा था, लेकिन क्योंकि 'शर्तों' विकल्प सभी प्रश्नों पर लागू किया गया था और, पहले व्यक्ति पर, यह थ्रेड टेबल की अनुपस्थिति के कारण दुर्घटनाग्रस्त हो गया।

  • रूप api55 कहा, 'शामिल' सरणी के अंदर की स्थिति का उपयोग कर इसे थ्रेड तालिका का उपयोग कर प्रश्नों का केवल उन्हें लागू होगा: इस जानने के बाद, वहाँ दो संभव समाधान हैं। लेकिन ऐसा करने से समस्या बनी रहती है, क्योंकि हमारे पास बहुत सारे प्रश्न हैं।

  • जैसा कि मोज़ मॉरिस ने कहा था, रेटिंग के लिए थ्रेड मॉडल को बाध्य करना भी काम करेगा, और यह एक ही क्वेरी करेगा, जो हम चाहते हैं। समस्या यह है कि मैं देखता हूं कि संबंधों को छोड़ने वाले पैच के रूप में मॉडल को betweem और केकेपीएचपी दर्शन का पालन नहीं करता है।

मैं सही रूप api55 समाधान चिह्नित क्योंकि यह ठोस समस्या मैं था हल करती है, लेकिन दोनों समस्या का समाधान दे।

उत्तर

5

सबसे पहले, क्या आपने एपमोडेल में एक्टिव कंटेनर वैरिएबल डाला है ??इसके बिना यह beahaviour बिल्कुल काम नहीं करेगा (मुझे लगता है कि यह सही ढंग से काम नहीं कर रहा है क्योंकि यह थ्रेड तालिका में शामिल नहीं हुआ है)

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

कुछ इस

appModel

public $actsAs = array('Containable'); 

रेटिंग नियंत्रक की तरह

$this->Rating->Activity->Thread->Forum->find('count', array(
    'contain' => array(
     'Thread' => array(
      'Activity' => array(
       'Rating' => array (
         'fields' => array ('Rating.*') 
       ) 
      ) 
     ) 
    ), 
    'conditions' => array(
     'Forum.id' => 1 
    ) 
)); 

तो अगर आप रेटिंग तालिका में केवल एक मूल्य की जरूरत है सिर्फ सेट का उपयोग ।

आईटी वैसे भी काम आप इसे किया था चाहिए, लेकिन मैं forum_id वहाँ का उपयोग नहीं करने sugest, लेकिन स्थिति में अंदर इस

'contain' => array(
    'Activity' => array(
     'Thread' => array(
       'conditions' => array('Thread.forum_id' => 1) 
     ) 
    ) 
), 

भी तरह होते हैं, कभी नहीं रखने योग्य behaviuor का उपयोग कर मॉडल में actsAs चर भूल (या ऐप मॉडल में)

+0

थ्रेड सरणी के अंदर 'स्थितियों' को स्थानांतरित करना काम नहीं करेगा क्योंकि परिणाम 'थ्रेड' सरणी के साथ बाकी सब कुछ के लिए वापस लौटाए जाएंगे। –

+0

@MozMorris यह सच है, क्योंकि इसमें शामिल हो गया है ... लेकिन यदि वह इसे शीर्ष (फोरम/थ्रेड से) चलाता है तो उसे सभी रेटिंग या खाली मिल जाएगी, हालांकि इसमें बहुत परेशान पेड़ होगा (मैं आमतौर पर लिंक करने योग्य का उपयोग करता हूं व्यवहार) – api55

+0

उत्तर देने के लिए धन्यवाद। मैंने कोशिश की कि लिंक पर दिए गए कोड पर और क्वेरी 'SELECT COUNT (*) फोरम एएस फोरम से फोरम.आईडी = 1' के रूप में गिनती है। मेरे पास पहले से ही एपमोडेल और सबकुछ पर कंटेनरिव व्यवहार सेट है। मुझे नहीं पता कि मेरे पास कुछ कॉन्फ़िगरेशन समस्या है या कुछ है, लेकिन ऐसा लगता है कि यह सही तरीके से काम नहीं कर रहा है। –

2

whist मुझे api55 के समाधान पसंद है, मुझे लगता है कि परिणाम थोड़ा गन्दा हैं - इस बात पर निर्भर करता है कि आप जो डेटा अनुमान लगाते हैं उसके साथ क्या करना चाहते हैं।

मुझे लगता है कि जब आप 'में शामिल' विधि आप इस विधि का उपयोग करने के बारे में बात कर रहे थे का उपयोग कर कहा:

$this->Rating->bindModel(array(
    'belongsTo' => array(
    'Thread' => array(
     'foreignKey' => false, 
     'conditions' => 'Thread.id = Activity.thread_id', 
    ), 
    'Forum' => array(
     'foreignKey' => false, 
     'conditions' => 'Forum.id = Thread.forum_id' 
    ) 
) 
)); 

$ratings = $this->Rating->find('all', array(
    'conditions' => array(
    'Forum.id' => 1 // insert forum id here 
) 
)); 

यह सिर्फ मेरे लिए थोड़ा क्लीनर लगता है, और आप का उपयोग कर के बारे में चिंता करने की जरूरत नहीं आपके AppModel में कंटेनर व्यवहार। ध्यान देने योग्य।

+0

यदि आपको गिनती की आवश्यकता है, तो स्पष्ट रूप से 'सभी' को 'गिनती' के साथ बदलें। :) –

+0

मैंने कभी एक्सडी के बारे में सोचा नहीं, लेकिन यह सच है कि इसका क्लीनर, दूसरी तरफ कई रिकर्सन देता है ... – api55

+0

आपके उत्तर के लिए धन्यवाद, जो इस उदाहरण पर काम करेगा। समस्या यह है कि वास्तविक एप्लिकेशन पर मुझे इसे कई बार करना है और मैं इसे और अधिक मॉड्यूलर करना चाहता हूं ("सक्षम" मॉडल का उपयोग करने के लिए एक सरणी है)। जो भी आप कहते हैं वह करना मुझे हर समय सभी शर्तों को भी सेट करना चाहिए। इसके अलावा, यह मुझे खराब करता है कि यह काम नहीं कर रहा है, यही वह है जो कंटेनर व्यवहार के लिए होना चाहिए, मुझे नहीं पता कि मुझे कुछ याद आ रहा है या नहीं। वैसे भी शुक्रिया। –

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