2009-02-24 7 views
43

में एक मणि से मॉड्यूल विधि को ओवरराइड करना ओरेकल के मेरे संस्करण पर will_paginate मणि टूट गया है। WillPaginate मॉड्यूल में डिफ़ॉल्ट paginate_by_sql विधि एक क्वेरी में एक अतिरिक्त 'AS' डालने और इसे असफल होने का कारण बन रही है।रेल

कोड स्वयं आसानी से तय किया गया है, लेकिन मुझे यकीन है कि रेल मेरे परिवर्तन को लेने के लिए सबसे अच्छा तरीका नहीं है।

मैं खुद को मणि में कोड नहीं बदलना चाहता, क्योंकि यह मेरे कोड को अन्य मशीनों पर तोड़ देगा।

मैं एक lib/test.rb युक्त फ़ाइल बनाने की कोशिश की:

module WillPaginate 
    def paginate_by_sql 
    (my code goes here) 
    end 
end 

और यह environment.rb से की आवश्यकता होती है, लेकिन यह मेरे परिवर्तन उठा नहीं है। मैंने इसे नियंत्रकों/application.rb से भी जरूरी करने की कोशिश की, लेकिन फिर से, मेरे परिवर्तनों को नहीं उठाया।

अस्थायी रूप से, मुझे इसे विशिष्ट मॉडल के भीतर विधि को ओवरराइड करके काम करने के लिए मिला, लेकिन यह एक हैक का थोड़ा सा है, और इसका मतलब है कि मैं इस परियोजना में किसी भी अन्य मॉडल पर इसका उपयोग नहीं कर सकता।

मुझे यकीन है कि ऐसा करने का एक आसान तरीका है, लेकिन मुझे Google का उपयोग करके इसे ट्रैक करने में कोई भाग्य नहीं है।

+0

यदि मणि कोड टूटा हुआ है, निश्चित रूप से यह हर जगह टूटा हुआ है? क्या आपने परियोजना के साथ एक बग लॉग किया है? http://wiki.github.com/mislav/will_paginate/report-bugs –

+0

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

उत्तर

27

क्या आप इच्छा काम कर रहे हैं, लेकिन अपने कोड इस तरह दिखेगा की जरूरत है:

module WillPaginate 
    module Finder 
    module ClassMethods 
     def paginate_by_sql(sql, options) 
     # your code here 
     end 
    end 
    end 
end 

दूसरे शब्दों में,, finder.rb में जाने मॉड्यूल हेडर और विधि आप ओवरराइड करना चाहते को छोड़कर सब कुछ को नष्ट , फिर lib में फ़ाइल में सहेजें और पर्यावरण.आरबी में शामिल करें। वोला, तत्काल बंदर पैच!

+0

कूल। धन्यवाद। यह चाल है =) –

+13

यह प्रारंभकर्ता 'कॉन्फ़िगर/प्रारंभकर्ता' में होना चाहिए - इसे 'environment.rb' फ़ाइल में न रखें! – Tilo

61

एक अधिक संक्षिप्त समाधान:

WillPaginate::Finder::ClassMethods.module_eval do 
def paginate_by_sql sql, options 
    # Your code here 
end 
end 

config में एक प्रारंभकर्ता फ़ाइल में कोड रखो/initializers। कोड लोड करने के लिए यह सही जगह है जिसे पर्यावरण लोड होने पर चलाने की आवश्यकता होती है। यह आपके कोड का बेहतर आयोजन करता है, जिससे प्रत्येक फ़ाइल का इरादा स्पष्ट हो जाता है, इस प्रकार बग को ट्रैक करना आसान हो जाएगा। पर्यावरण को अव्यवस्थित मत करो। आरबी!

+0

अंतर्निहित क्लास 'ऑटोलोड' के माध्यम से लोड होने पर दिलचस्प कोने का मामला: http://stackoverflow.com/questions/8736451/override-a-method-inside-a-gem-from-another-gem – Tilo

+1

बहुत अच्छा। नए 'paginate_by_sql' में, क्या मैं अपने पूर्व संस्करण तक पहुंच सकता हूं? क्या मैं कुछ सुपर (एसक्यूएल, विकल्प) 'कह सकता हूं? –

38

ठीक है, मैं बस अपने जैसे लोगों के लिए यह आसान बनाने जा रहा हूं जो अभी भी आते हैं और फिर भी अन्य उत्तरों को पढ़ने के बाद थोड़ा सा संघर्ष करते हैं।

पहले कोड है कि आप (आप आसानी से इस का उपयोग करते हुए pry मिल सकता है) आप मणि में परिवर्तित करना चाहते हैं, और फिर आगे Code का चयन कोड की पंक्ति को खोजते हुए GitHub रेपो पर बदलने के लिए करना चाहते हैं के बजाय Issues

enter image description here

enter image description here

अगला कॉपी Conte छोड़ दिया उस मॉड्यूल का एनटी जिसे आप बदलना चाहते हैं और इसे अपने कॉन्फ़िगर/प्रारंभकर्ता फ़ोल्डर के अंदर एक उचित नामित .rb फ़ाइल में रखें।यहाँ एक उदाहरण है:

Forem::TopicsHelper.module_eval do 
    def link_to_latest_post(post) 
    text = "#{time_ago_in_words(post.created_at)} #{t("ago_by")} #{post.user}" 
    link_to text, forum_topic_path(post.topic.forum, post.topic, :anchor => "post-#{post.id}") 
    end 
end 

अब, कोड में कोई भी अतिरिक्त परिवर्तन करना और अपने सर्वर को पुनः आरंभ:

module Forem 
    module TopicsHelper 
    def link_to_latest_post(post) 
     text = "#{time_ago_in_words(post.created_at)} #{t("ago_by")} #{post.user}" 
     link_to text, forum_topic_path(post.topic.forum, post.topic, :anchor => "post-#{post.id}") 
    end 
    end 
end 

अब, यह करने के लिए बदल जाते हैं।

दूर आप जाओ!

+0

क्या आप इस तरह की मूल विधि को कॉल करने में सक्षम होंगे या आपके पास इसके लिए alias_method_chain (रेल में वैसे भी) है? – Machisuji

+0

मूल विधि – Abram

+1

धन्यवाद @ अब्राहम! यह बहुत उपयोगी था! – KavitaC