2010-09-28 16 views
22

मैं कुछ जटिल प्रश्नों के साथ will_paginate का उपयोग कर रहा हूं और यह कुल रिकॉर्ड्स की संख्या की गणना करने में असमर्थ है (पृष्ठ लिंक की उचित संख्या प्रदर्शित करने के लिए) - अर्थात् एकाधिक कॉलम द्वारा समूहित करने के कारण।मैं ActiveRecord # द्वारा बनाए गए SQL कथन को वास्तव में निष्पादित किए बिना कैसे प्राप्त कर सकता हूं?

तो, मैं चयन क्वेरी प्राप्त करने का इरादा रखता हूं, जिसका उपयोग वास्तव में इसे निष्पादित किए बिना सभी रिकॉर्ड्स को पुनर्प्राप्त करने के लिए किया जाएगा, और रिकॉर्ड की संख्या प्राप्त करने के लिए इसे SELECT COUNT(*) FROM ... मैन्युअल रूप से लपेटें।

कोई विचार यह कैसे करना है?

संपादित करें: मैं रेल 2.3.x

+0

की (http://stackoverflow.com/questions/974020/get-the-sql-that- [एसक्यूएल कि एक निश्चित विधि या named_scope से क्रियान्वित किया होगा जाओ] संभव डुप्लिकेट एक निश्चित-विधि-या-नामित-स्कोप से-निष्पादित-से-निष्पादित किया जाएगा) –

उत्तर

34

उपयोग कर रहा हूँ रेल 3 के लिए:

बाहर चेक Rails 3 docs पर ActiveRecord :: रिलेशन डॉक्स।

# get the relation 
rel = User.complex_scope.chained_complex_scope 

# get the SQL 
# this does not execute the query 
sql = rel.to_sql 

# find out how many records 
# this executes the query behind the scenes 
count = rel.size 
+1

धन्यवाद, जब हम 3 पर माइग्रेट करते हैं तो मैं इसे ध्यान में रखूंगा। मैं यह उल्लेख करना भूल गया था कि हम अभी भी 2.3.x का उपयोग कर रहे हैं, माफ़ कीजिये। –

+0

यह रेल 4 के लिए भी काम करता है :) –

0

कुछ समय पहले, मैं एक प्लग इन को इस के लिए कहा जाता है sql_display इस्तेमाल किया।

>> Post.sql 
=> "SELECT * FROM \"posts\"" 

>> Post.sql(:order => "id DESC") 
=> "SELECT * FROM \"posts\" ORDER id DESC" 

>> Post.scoped({}).sql 
=> "SELECT * FROM \"posts\"" 

>> Post.count_sql 
=> "SELECT count(*) AS count_all FROM \"posts\"" 
+0

धन्यवाद, मैं इसे आज़मा दूंगा। क्या आपको शायद पता चलेगा कि यह एआर व्यवहार की नकल करने वाले एसक्यूएल का निर्माण करता है, या किसी भी तरह से एआर लपेटता है? अर्थात। क्या मैं भरोसा कर सकता हूं कि यह वही क्वेरी 'एआर # ढूंढ' देगा? –

0

दुर्भाग्य से रेल 2.x में यह वास्तव में काफी कठिन है। मैंने पहले स्टैक ओवरफ़्लो पर एक समान प्रश्न पोस्ट किया है और एक रास्ता खोजने के लिए रेल के स्रोत कोड में गहरा खोदना समाप्त कर दिया है। यह सिर्फ इस अनुमति देने के लिए वास्तुकार नहीं है।

जो मैंने समाप्त किया वह लेनदेन में क्वेरी चला रहा था जिसे मैंने वापस ले लिया था, और लेनदेन की लंबाई के लिए लॉगर को अपने स्वयं के स्ट्रिंगियो ऑब्जेक्ट पर सेट करना था जिसे मैं पढ़ सकता था।

इस स्मृति से है, लेकिन उम्मीद है कि आपको यह काफी समझ में अगर यह काम नहीं करता है इसे समायोजित करने की:

Model.transaction do 
    Model.logger = str = StringIO.new 
    Model.complex_scope.chained_complex_scope 
    Model.logger = ActiveRecord::Base.logger 
    str.rewind 
    str = str.read 

    # perform some regex on str to get the actual query 

    raise ActiveRecord::Rollback 
end 

यह नरक के रूप में बदसूरत है और मैं इसे कभी पसंद आया (मैं एक sql { Model. complex_scope.chained_complex_scope } में लपेटा), लेकिन यह थोड़े मेरे लिए काम करता था (मैंने केवल इसे विकास में इस्तेमाल किया था, इसलिए मुझे त्रुटियों के लिए कुछ सहिष्णुता थी)

9

ऐसा लगता है कि रेल 2.x में, ActiveRecord::Base#construct_finder_sql नामक एक निजी विधि का उपयोग किया जा सकता है, मुझे इसे और अधिक परीक्षण करने की आवश्यकता है और देखें कि यह मेरे लिए काम करेगा या नहीं:

ActionType.find(:all, :select => 'hosted, top_action_type, count(*) as count', :group => 'hosted, top_action_type').count 
#=> 6 
sql = ActionType.send :construct_finder_sql, :select => 'hosted, top_action_type, count(*) as count', :group => 'hosted, top_action_type' 
#=> "SELECT hosted, top_action_type, count(*) as count FROM "action_types" GROUP BY hosted, top_action_type" 
ActionType.count_by_sql "SELECT COUNT(*) FROM (#{sql}) a" 
#=> 6 
+1

परीक्षण किया गया और वास्तव में ठीक काम करता है। मुझे लगता है मुझे अपना जवाब स्वीकार करना चाहिए।:/ –

+0

* * शामिल * जोड़ने का कोई तरीका है? –

0

मुझे पता है कि सवाल "इसे निष्पादित किए बिना" पूछता है, लेकिन #explain विधि बहुत उपयोगी है और कम से कम यहां उल्लेख किया जाना चाहिए। धीमे प्रश्नों को डीबग करने के लिए यह बेहद उपयोगी है।

नोट: हालांकि यह क्वेरी निष्पादित करता है।

http://guides.rubyonrails.org/v3.2.8/active_record_querying.html#running-explain

$ User.where("users.email LIKE '%longford%'").explain 

    User Load (0.6ms) SELECT `users`.* FROM `users` WHERE (users.email LIKE '%longford%') 
=> EXPLAIN for: SELECT `users`.* FROM `users` WHERE (users.email LIKE '%gmail%') 
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 
| 1 | SIMPLE  | users | ALL | NULL   | NULL | NULL | NULL | 5 | Using where | 
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 
1 row in set (0.00 sec) 
संबंधित मुद्दे

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