Grails

2012-06-26 15 views
11

में अभिभावक डोमेन क्लास में "अंतिम अद्यतन" फ़ील्ड अपडेट करें मेरे पास एक मूल डोमेन क्लास है जिसमें hasMany अन्य डोमेन क्लास है। माता-पिता और बच्चे दोनों डोमेन कक्षाओं में lastUpdated और dateCreated फ़ील्ड हैं। मेरी समस्या यह है कि जब मैं एक बाल डोमेन कक्षा अद्यतन करता हूं, तो मुझे उस परिवर्तन को प्रतिबिंबित करने के लिए मूल डोमेन क्लास की आवश्यकता होती है और इसके lastUpdated फ़ील्ड को भी अपडेट किया जाता है।Grails

क्या ग्रेल्स प्रदान करता है कि अभिभावक और बच्चे के बीच कोई मैपिंग या अन्य कॉन्फ़िगरेशन है जो इस सुविधा को लागू करेगा?

अद्यतन

मैं जोड़ा बच्चे डोमेन वर्ग के लिए निम्नलिखित लाइनों:

def beforeUpdate = { 
    parent.lastUpdated = new Date() 
} 

मैं भी कि जब मैं एक बच्चे को अद्यतन, मैं भी बचाने के लिए किया था नियंत्रक में सुनिश्चित करने के लिए किया था माता-पिता के साथ-साथ नए lastUpdated फ़ील्ड को जारी रखने के लिए। ऐसा लगता है कि यह ठीक काम करता है, लेकिन मैं अभी भी जानना चाहूंगा कि मैपिंग या ऐसा कुछ ऐसा है जो ऐसा करेगा।

+0

"मुझे यह भी सुनिश्चित करना था कि जब मैंने एक बच्चे को अद्यतन किया, तो मुझे माता-पिता को भी सहेजना पड़ा" <--- मुझे लगता है कि आवश्यक नहीं है ... सहेजें() को हटाने का प्रयास करें माता-पिता और देखो कि यह बिना काम करता है –

+0

Grails 2.2.0 के साथ, पहले अद्यतन तकनीक काम करता है। माता-पिता को सहेजना जरूरी नहीं है और आपके पास कोई डबल सेव व्यवहार नहीं होगा। तो आपको किसी भी फॉर्मूला की आवश्यकता नहीं है, केवल श्रोता। – Guillaume

उत्तर

2

मुझे लगता है कि आपका सुझाया गया कार्यान्वयन खराब हो जाएगा। lastUpdated दिनांक मैन्युअल रूप से सेट करके parent अद्यतन कर रहे हैं, जो पर lastUpdated अद्यतन करने के बाद फिर से गंदे जांच करने के बाद grails का कारण बन सकता है। यदि ऐसा है, तो आप वास्तव में एक अंतिम अद्यतन समय के साथ समाप्त हो जाएंगे जो आपके द्वारा निर्धारित मूल तिथि के बाद हुआ था। आपके परीक्षण में, यह केवल कुछ (मिली) सेकंड हो सकता है, लेकिन आप इसकी गारंटी नहीं दे सकते।

न केवल यह, लेकिन आपके कार्यान्वयन को बनाए रखना मुश्किल है क्योंकि आपने माता-पिता और बच्चे के युग्मन में वृद्धि की है।

क्या मैं एक और कार्यान्वयन का सुझाव दे सकता हूं? अंतिम अद्यतन फ़ील्ड उस समय का प्रतिनिधित्व करना चाहिए जब विशिष्ट डोमेन ऑब्जेक्ट अपडेट किया गया था। जिस तारीख को आप ढूंढ रहे हैं वह बिल्कुल वही बात नहीं है, इसलिए मैं "गलत" तरीके से मौजूदा सम्मेलन का उपयोग करने की कोशिश नहीं करता। ऐसा लगता है कि जिस तारीख को आप मूल वस्तु के लिए चाहते हैं वह "पिछली बार जब बच्चा संशोधित किया गया था"।

इसके बजाय एक सूत्र का उपयोग करें।

ऐसा करने के लिए, आप formula का उपयोग कर सकते हैं। सूत्र के साथ, आप मूल वस्तु को सीधे संशोधित किए बिना बिल्कुल वही प्राप्त करते हैं, और आप अभी भी गतिशील खोजकर्ताओं और अन्य Grails चीनी का उपयोग कर सकते हैं।

class Parent { 
    ... 
    Date lastChildUpdated 

    static hasMany = [ children: Child ] 

    static mapping = { 
     ... 
     lastChildUpdated formula: '(SELECT max(c.last_updated) FROM child c WHERE c.parent_id = id)' 
    } 
} 

जब भी आप डेटाबेस से ऑब्जेक्ट पढ़ते हैं तो GORM फॉर्मूला का मान लोड करेगा। अब, जब भी आप एक बच्चे को बचाते हैं, तो अभिभावक को उस संपत्ति के लिए सही मूल्य होगा जो माता-पिता को छूए बिना।

+0

क्या वह वास्तव में काम करता है ?, मैंने पहले या किसी भी जगह पर यह कोशिश नहीं की है जहां मैंने इस प्रकार की चीज़ को और देखा है ... !!! – sanghavi7

+0

क्षमा करें, मैंने आपको एक डाउनवोट दिया है: सुझाए गए ओपी का समाधान कार्य और आपकी भावना गलत थी। और सूत्र बहुत सारे नए बदलाव ला रहा है: बच्चों के लिए टाइमस्टैम्प भी, एक सूत्र जो शायद नहीं कहा जा सकता है अगर आपकी मूल इकाई को फ्लश नहीं किया गया है और फिर पूछताछ की गई है ... – Guillaume

+1

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

0

मेरी परियोजना में से एक में जहां डोमेन जैसा था। एक प्रोग्राम में कई विज्ञापन सामग्री हैं और हमारे पास विज्ञापन सामग्री, FlashAd, ImageAd आदि के उप-वर्ग हैं। उपयोगकर्ता FlashAds, imageAds आदि वाले प्रोग्राम को फ़िल्टर करने की क्षमता चाहते हैं। अब मुझे कक्षा संपत्ति के आधार पर फ़िल्टरिंग करने की आवश्यकता है जिसे हम डेटाबेस तालिका में है (जब तालिका तालिका PerHierarchy सच है)। इसलिए मैंने इस संपत्ति को प्राप्त करने के लिए अपने डोमेन क्लास में कुछ बदलाव किए।

class AdvertisingMaterial { 
     String className 

     static constraints = { 
       className(nullable: true) 
     } 

     static mapping = { 
       className formula: 'CLASS' 
     } 
} 

अब मैं अपने गतिशील खोजकर्ताओं और मानदंड क्वेरी में इस कक्षा नाम फ़ील्ड का उपयोग कैसे कर सकता हूं।तो मैं कुछ कर सकता हूं जैसे

List<AdvertisingMaterial>adMaterials=AdvertisingMaterial.findAllByClassName("com.project.FlashAd") 

static mapping = { 
       fullName formula: "CONCAT(FIRST_NAME,' ',LAST_NAME)" 
       totalAmount formula: "SUM(AMOUNT)" 
} 
1

मैंने एक हैक का उपयोग किया। मैं अपने माता पिता के डोमेन वर्ग के लिए एक Long updateTrigger क्षेत्र को शामिल किया है और एक touch विधि:

class Parent { 
    Long updateTrigger 

    static mapping = { 
     autoTimestamp true 
    } 

    static constraints = { 
     updateTrigger(nullable:true) 
    } 

    public touch() { 
     if (updateTrigger == null) updateTrigger = 0 
     updateTrigger++ 
     this 
    } 

अद्यतन में/बच्चे नियंत्रक के कार्यों बचाने के लिए, मैं सिर्फ फोन:

child_instance.save() // save the child 
child_instance.parent.touch().save() // updates parent's time stamp 

यह updateTrigger मान बढ़ाएगा, और save() स्वचालित रूप से lastUpdated फ़ील्ड को autoTimestamp पर true पर सेट करने के लिए स्वचालित रूप से अपडेट करेगा pping। updatedTrigger को शून्य के रूप में सेट किया गया है ताकि यह किसी भी मौजूदा डेटाबेस तालिका को अमान्य नहीं कर सके और इसलिए किसी भी डोमेन वर्ग में कभी भी जोड़ा जा सकता है।