2015-11-10 6 views
16

हमने हाल ही में रेल 4.1 से 4.2 रेल करने के लिए उन्नत और अरेल + ActiveRecord का उपयोग कर, क्योंकि हम इस प्रकार की त्रुटि हो रही है के साथ समस्याओं को देख रहे हैं:अरेल + रेल 4.2 के कारण समस्याओं (बाइंडिंग खो दिया जा रहा)

ActiveRecord::StatementInvalid: PG::ProtocolViolation: ERROR: bind message supplies 0 parameters, but prepared statement "" requires 8 

यहाँ कोड है कि टूट रहा है:

customers = Customer.arel_table 

     ne_subquery = ImportLog.where(
     importable_type: Customer.to_s, 
     importable_id: customers['id'], 
     remote_type: remote_type.to_s.singularize, 
     destination: 'hello' 
    ).exists.not 

     first = Customer.where(ne_subquery).where(company_id: @company.id) 
     second = Customer.joins(:import_logs).merge(
     ImportLog.where(
      importable_type: Customer.to_s, 
      importable_id: customers['id'], 
      remote_type: remote_type.to_s.singularize, 
      status: 'pending', 
      destination: 'hello', 
      remote_id: nil 
     ) 
    ).where(company_id: @company.id) 

     Customer.from(
     customers.create_table_alias(
      first.union(second), 
      Customer.table_name 
     ) 
    ) 

हम पता लगा क्वेरी के पहले भाग को हल करने के लिए कैसे की तरह Customer.where के भीतर होने का exists.not ले जाकर (होने बाइंडिंग नहीं की एक ही रेल बग में चल) इसलिए:

ne_subquery = ImportLog.where(
     importable_type: Customer.to_s, 
     importable_id: customers['id'], 
     destination: 'hello' 
    ) 

    first = Customer.where("NOT (EXISTS (#{ne_subquery.to_sql}))").where(company_id: @company.id) 

यह काम करने के लिए लग रहा था, लेकिन हम कोड की इस पंक्ति के साथ एक ही मुद्दा में भाग:

first.union(second) 

जब भी हम क्वेरी के इस हिस्से चलाने के लिए, बाइंडिंग खो दिया हो। पहला और दूसरा दोनों सक्रिय रिकॉर्ड ऑब्जेक्ट्स हैं, लेकिन जैसे ही हम उन्हें "संघ" करते हैं, वे बाध्यकारी खो देते हैं।

हमने क्वेरी के माध्यम से साइकिल चलाने की कोशिश की और मैन्युअल रूप से बाइंडिंग को बदल दिया लेकिन यह ठीक से काम नहीं कर सका। इसके बजाय हमें क्या करना चाहिए?

संपादित करें:

हम मैन्युअल रूप से भी पहले और दूसरे, और फिर से बाँध मान निकालने इसलिए जैसे अरेल वस्तु में उन्हें जगह करने की कोशिश की:

union.grep(Arel::Nodes::BindParam).each_with_index do |bp, i| 
    bv = bind_values[i] 
    bp.replace(Customer.connection.substitute_at(bv, i)) 
end 

हालांकि, यह विफल रहता है क्योंकि:

NoMethodError: undefined method `replace' for #<Arel::Nodes::BindParam:0x007f8aba6cc248> 

यह रेल गिथब रेपो में सुझाया गया एक समाधान था।

+0

मुझे लगता है कि कुछ प्रश्नों को बेहतर लिखा जा सकता है (उदाहरण के लिए: दूसरा = ग्राहक। Joins (: import_logs)। कहीं (import_logs: {/ * आयात लॉग इन स्थितियां * /}) ... ... मुझे नहीं मिलता आप पूरा करने की कोशिश कर रहे हैं। – muZk

उत्तर

0

मुझे पता है कि यह प्रश्न थोड़ा पुराना है, लेकिन त्रुटि परिचित लगती है। मेरे पास कुछ नोट्स और रिपोजिटरी में हमारा समाधान था, इसलिए मैंने सोचा कि मैं साझा करूंगा।

त्रुटि हम प्राप्त कर रहे थे:

PG::ProtocolViolation: ERROR: bind message supplies 0 parameters, but prepared statement "" requires 1

तो जैसा कि आप देख सकते हैं, हमारे स्थिति थोड़ी अलग है। हमारे पास 8 बाध्य मूल्य नहीं थे। हालांकि, हमारे एकल बांध मूल्य अभी भी गिरफ्तार किया जा रहा था। मैंने इसे सामान्य रखने के लिए चीजों का नाम बदल दिया।

first_level = Blog.all_comments 
second_level = Comment.where(comment_id: first_level.select(:id)) 
third_level = Comment.where(comment_id: second_level.select(:id)) 

Blog.all_comments वह जगह है जहां हमारे पास सिंगल बाइंड वैल्यू है। वह टुकड़ा है जिसे हम खो रहे हैं।

union = first_level.union second_level 
union2 = Comment.from(
    Comment.arel_table.create_table_alias union, :comments 
).union third_level 

relation = Comment.from(Comment.arel_table.create_table_alias union2, :comments) 

हमने आपके जैसा एक संघ बनाया है, सिवाय इसके कि हमें तीन अलग-अलग प्रश्नों को संघबद्ध करने की आवश्यकता है।

इस बिंदु पर खोए गए बाध्य मूल्य प्राप्त करने के लिए, हमने एक सरल असाइनमेंट किया। अंत में, यह आपके मामले की तुलना में थोड़ा आसान है। हालांकि, यह सहायक हो सकता है।

relation.bind_values = first_level.bind_values 
relation 

वैसे, यहाँ GitHub issue जबकि इस पर काम कर हमने पाया है। हालांकि इस प्रश्न को पोस्ट करने के बाद से इसमें कोई अपडेट नहीं दिखता है।

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