2008-09-22 14 views
11

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

उदाहरण, मेरे पास एक व्यक्ति तालिका स्रोत तालिका है। Source.source_id स्रोत तालिका में एक पंक्ति में मानचित्र। प्रत्येक व्यक्ति के पास एक स्रोत होता है, और प्रत्येक स्रोत में कोई भी या कई व्यक्ति पंक्तियां नहीं होती हैं।

cacheCounter जब मैं किसी व्यक्ति के स्रोत को बदलता हूं तो बहुत अच्छा काम कर रहा है। यह Source.Person_Count में वृद्धि करता है। ठंडा।

लेकिन जब यह बढ़ता है, तो यह इसे किसी व्यक्ति के गंतव्य स्रोत में जोड़ता है, लेकिन इसे पुराने मान से नहीं हटाता है। मैंने afterSave में कोशिश की, लेकिन उसने कुछ भी नहीं किया।

तो मैंने अपने मॉडल में afterSave के लिए कुछ कोड लिखा जो स्रोत स्रोत_आईडी घटाएगा, लेकिन यह हमेशा तब भी किया जब मैं source_id को भी नहीं बदल रहा था। (तो गिनती नकारात्मक हो गई)।

मेरा प्रश्न: क्या यह बताने का कोई तरीका है कि CakePHP में मॉडल में कोई फ़ील्ड बदल गया है या नहीं?

उत्तर

17

एक क्षेत्र में परिवर्तनों की निगरानी के लिए, आपको कोई बदलाव नहीं कहीं और की आवश्यकता के साथ अपने मॉडल में इस तर्क का उपयोग कर सकते हैं:

function beforeSave() { 
    $this->recursive = -1; 
    $this->old = $this->find(array($this->primaryKey => $this->id)); 
    if ($this->old){ 
     $changed_fields = array(); 
     foreach ($this->data[$this->alias] as $key =>$value) { 
      if ($this->old[$this->alias][$key] != $value) { 
       $changed_fields[] = $key; 
      } 
     } 
    } 
    // $changed_fields is an array of fields that changed 
    return true; 
} 
+0

मैं कॉलबैक पर स्पष्ट नहीं हूं। क्या इस फ़ंक्शन को नियंत्रक में नहीं बुलाया जाना चाहिए? मैं इसे कैसे कार्यान्वित करूं? –

+0

@ माइकस। आप इसे मॉडल वर्ग में जोड़ देंगे। – 472084

-1

देखें कि "सहेजने" कुछ प्रकार के डीबीएएल कॉल का उपयोग करता है जो "प्रभावित पंक्तियों" को लौटाता है, आमतौर पर यह तय होता है कि आखिरी क्वेरी डेटा बदल गई है या नहीं। क्योंकि यदि ऐसा नहीं होता है, तो UPDATE-स्टेटमेंट के बाद प्रभावित पंक्तियां 0

+0

धन्यवाद। मैं वास्तव में सोच रहा था कि संपादन कार्रवाई के बाद संपादन कार्रवाई से पहले मूल्य बदल गया है, एसक्यूएल को पूर्व-सहेजें। – Justin

+0

मुझे यकीन नहीं है कि मैं समझता हूं, क्या आप SQL कॉल से बचना चाहते हैं? – Till

0

संपादन बार-बार होते हैं, इसलिए अपडेट करने से पहले एक और चयन कोई बड़ा सौदा नहीं है, इसलिए, सहेजने से पहले रिकॉर्ड प्राप्त करें, इसे सहेजें , आपके द्वारा सहेजे जाने से पहले डीबी से प्राप्त डेटा के साथ संपादन फ़ॉर्म में सबमिट किए गए डेटा की तुलना करें, यदि यह अलग है, तो कुछ करें।

1

संपादन दृश्य में, उस क्षेत्र के लिए एक और छुपा फ़ील्ड शामिल करें जिसे आप मॉनीटर करना चाहते हैं लेकिन "_prev" जैसे कुछ फ़ील्ड नाम को प्रत्ययित करें और उस फ़ील्ड के वर्तमान मान को मान सेट करें जिसे आप मॉनिटर करना चाहते हैं। फिर अपने नियंत्रक की संपादन कार्रवाई में, कुछ फ़ील्ड बराबर नहीं होने पर कुछ करें। जैसे

echo $form->input('field_to_monitor'); 
echo $form->hidden('field_to_monitor_prev', array('value'=>$form->value('field_to_monitor'))); 
+2

यह चीजों को करने का एक बहुत ही सुरक्षित तरीका नहीं है। फ़ायरबग वाला कोई भी _prev फ़ील्ड के मानों को बदल सकता है। मेरे विरोध में परिवर्तनों की जांच के लिए वास्तविक डेटाबेस से तुलना करना बेहतर होता है।मेरा जवाब देखें –

-1

आप getAffectedRows() किसी भी मॉडल वर्ग पर कॉल कर सकते हैं।

वर्ग मॉडल से

:

/** 
* Returns the number of rows affected by the last query 
* 
* @return int Number of rows 
* @access public 
*/ 
    function getAffectedRows() { 
     $db =& ConnectionManager::getDataSource($this->useDbConfig); 
     return $db->lastAffected(); 
    } 
+1

यह सवाल नहीं था कि सवाल क्या पूछ रहे थे। आपकी विधि केवल तभी कहती है जब डेटा बदल दिया गया था, लेकिन "क्या" फ़ील्ड नहीं बदले गए थे। –

7

को अलेक्जेंडर Morland उत्तर संदर्भ के साथ।

फ़िल्टर से पहले इसे लूप करने के बजाय इसके बारे में कैसे।

$result = array_diff_assoc($this->old[$this->alias],$this->data[$this->alias]); 

आपको कुंजी और साथ ही मूल्य भी मिलेगा।

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

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