我在使用will_paginate
時遇到了一些複雜的查詢,無法正確計算總記錄數(爲了顯示正確數量的頁面鏈接) - 即由於按多列分組。如何獲取由ActiveRecord#查找創建的SQL語句而不實際執行?
因此,我打算獲取SELECT查詢,該查詢將用於檢索所有記錄,而不實際執行它,並手動將它與SELECT COUNT(*) FROM ...
包裝在一起,以獲取記錄數。
任何想法如何做到這一點?
編輯:我使用Rails 2.3.x版本
我在使用will_paginate
時遇到了一些複雜的查詢,無法正確計算總記錄數(爲了顯示正確數量的頁面鏈接) - 即由於按多列分組。如何獲取由ActiveRecord#查找創建的SQL語句而不實際執行?
因此,我打算獲取SELECT查詢,該查詢將用於檢索所有記錄,而不實際執行它,並手動將它與SELECT COUNT(*) FROM ...
包裝在一起,以獲取記錄數。
任何想法如何做到這一點?
編輯:我使用Rails 2.3.x版本
對於Rails的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
謝謝,當我們遷移到3時,我會記住這一點。我忘記提及我們仍在使用2.3.x,抱歉。 – 2010-09-28 16:18:50
它也適用於Rails 4 :) – 2015-09-18 06:50:25
前段時間,我爲此使用了一個名爲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\""
謝謝,我會試試看。你可能知道它是構建SQL模仿AR行爲還是以某種方式包裝AR?即我可以相信它會給出完全相同的查詢'AR#find'會嗎? – 2010-09-28 18:57:15
不幸的是,在Rails 2.x中,這實際上很難。我之前在Stack Overflow上發佈了一個類似的問題,並最終深入Rails的源代碼以找到方法。它只是沒有建立在一種方式來允許這一點。
我最終做的是在我回退的事務中運行查詢,並將事務的長度設置爲我自己可以讀取的自己的StringIO對象。
這是從內存,但希望你明白了足夠的調整它,如果它不工作:
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 }
),但它有點爲我工作(我只用它在開發雖然,所以我有一些容錯的錯誤)
看來,在Rails 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
經過測試,確實可以正常工作。我想我應該接受自己的答案。:/ – 2010-11-20 18:13:50
有沒有辦法添加*:include *以及? – 2017-07-03 18:10:08
我知道這個問題詢問「沒有執行它」,但#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)
的[獲取,將來自特定方法或named_scope執行的SQL](http://stackoverflow.com/questions/974020/get-the-sql-that-可能重複將被執行的某種方法或命名範圍) – 2010-09-29 10:22:47