2012-11-09 18 views
9

मेरे पास एक मॉडल है जिसमें कई प्रकार हैं Imany, और has_many: मॉडल संबंधों के माध्यम से। उदाहरण के लिए, मेरे उपयोगकर्ता कक्षा में मेरे पास है:रेल में परिवर्तनों का पता लगाने के लिए है_many: रिश्ते के माध्यम से

has_many: भाषा, के माध्यम से: profile_languages ​​

मैं चाहते हैं क्या जब इन जोड़े या निकाले जाने 'User.changes' समारोह का उपयोग कर पता लगाने के लिए सक्षम होने के लिए है , जो उपयोगकर्ता के साथ बुलाए जाने वाले गुणों की एक सरणी देता है। language_ids = function।

क्या किसी और ने ऐसा करने का प्रयास किया है, या इसके साथ अनुभव है? ActiveModel पर

जानकारी में परिवर्तन समारोह: http://api.rubyonrails.org/classes/ActiveModel/Dirty.html

संपादित करें: के रूप में अनुरोध किया है, यहाँ मैं क्या कर रहा हूँ है।

उपयोगकर्ता के गुणों को असाइन किए जाने के बाद और इसे सहेजने से पहले, मैं बाहरी लॉग में किए गए सभी परिवर्तनों को लॉग इन करने के लिए .changes से लौटाए गए सभी मानों को देख रहा हूं।

तो अगर मैं u.name = "नया नाम" कहते हैं

तो u.changes रिटर्न {नाम: [ 'पुराना नाम', 'नया नाम']}

हालांकि, जब मैं एक पारित उपयोगकर्ता भाषा आईडी का एक समूह है, जैसे

u.language_ids = [4,5]

तो फिर वहाँ बनाया ProfileLanguage मॉडलों में से एक नंबर रहे हैं, और u.changes हैश खाली छोड़ दिया है।

मैं प्रोफाइल भाषा मॉडल में कुछ कॉलबैक बनाने का प्रयास कर रहा हूं जो मैन्युअल रूप से किसी प्रकार का हैश बना देगा, लेकिन मुझे आश्चर्य है कि यह वास्तव में सबसे अच्छा समाधान है या नहीं।

+0

हाय रॉन, क्या आप कृपया अपने प्रश्न के बारे में थोड़ा और विशिष्ट हो सकते हैं? शायद हमें दिखाएं कि आपने अभी तक क्या सेटअप किया है, इसलिए हमारे पास कुछ बंद होना है। – Noz

+0

क्या आपने कॉलबैक या पर्यवेक्षकों को देखा है? – Ari

+0

एक संपादन जोड़ा गया। उम्मीद है कि यह –

उत्तर

10

मेरे कुछ हद तक गंदे समाधान के साथ मैं अब जा रहा हूँ has_many समारोह के लिए कॉलबैक जोड़ने के लिए है:

has_many :languages, through: :profile_languages, 
     :after_add => :language_add, 
     :before_remove => :language_remove 

और एक कस्टम हैश को यह जानकारी है कि एक प्रोफाइल जब मैं कर रहा हूँ की बचत पर जाँच की जाएगी जोड़ने .changes फ़ंक्शन को देख रहे हैं।

+0

को स्पष्ट कर सकता है जो मेरे लिए काम नहीं करता है। ऐसा लगता है, जब आप बड़े पैमाने पर असाइनमेंट करते हैं (जैसे ओप भाषा_आईड्स के साथ किया जाता है) तो after_add और first_remove कॉलबैक ट्रिगर नहीं होते हैं। क्या मुझसे कुछ गलत हो रही है? – morgler

+0

यह काम करता है, फिर उन कॉलबैक को प्रत्येक निकालने वाली वस्तु को अलग से बुलाया जाता है। –

0

मुझे एक ही समस्या थी, मैं यह जांचने की कोशिश कर रहा था कि मॉडल अपडेट करते समय कोई नया रिश्ता बनाया गया या हटा दिया गया था या नहीं।

मैंने model.relationship.any? { |a| a.changed? } का उपयोग करने का प्रयास किया, लेकिन यह केवल मौजूदा वस्तुओं के क्षय के परिवर्तनों का पता लगाता है, इसलिए यह संबंधों के निर्माण और हटाने पर काम नहीं करता है। link

model.select { |a| a.new_record? || e.marked_for_destruction? }.any? का उपयोग करते हुए मैं सभी रिकॉर्ड है कि बनाया है या नष्ट किया जा रहा प्राप्त करने में सक्षम किया गया है:

एक समाधान के लिए खोज, मैं इस बहुत ही संक्षिप्त लेख जो हमारे समस्या का हल मिल गया।

a.changed? के साथ इसे जोड़कर मैं अपने रिश्ते में हर बदलाव प्राप्त कर सकता हूं।

+0

'accepts_nested_attributes_for' के साथ काम करता है, लेकिन आम तौर पर नहीं। – maxhs

0

मुझे पता है कि आप परिवर्तनों के एक पाठ आधारित लॉग को लागू करने के लिए देख रहे हैं, लेकिन मैं paper_trail मणि के माध्यम से पूर्ण ऑब्जेक्ट वर्जनिंग को देखने की सलाह दूंगा जो आप चाहते हैं।यह this functionality according to their README प्रदान करता है:

PaperTrail संघों के तीन प्रकार बहाल कर सकते हैं: है-एक, है-कई, और है-कई-के माध्यम से। ऐसा करने के लिए, आपको संस्करण_सॉसिएशन टेबल बनाने की आवश्यकता होगी, या तो रेलवे के साथ स्थापना समय पर paper_trail उत्पन्न करें: install --with-associations विकल्प या मैन्युअल रूप से। संबंधित रिकॉर्ड बदलते समय पेपरट्रेल उस तालिका में एसोसिएशन के संस्करणों और मॉडल के संस्करणों को सहसंबंधित करने के लिए अतिरिक्त जानकारी संग्रहीत करेगा।

मैं paper_trail की है-कई के माध्यम से सुविधा का इस्तेमाल किया है, लेकिन मैं संघों के बिना वस्तुओं के लिए यह प्रयोग किया जाता है, और इसे उत्कृष्ट और लागू करने में आसान पाया।

टेक्स्ट फ़ाइल लॉग के साथ-साथ यह डेटाबेस पेपर ट्रेल बनाने के लिए आप कॉलबैक में paper_trail's diff features का उपयोग कर सकते हैं।