How can I get SQL statement created by ActiveRecord#find without actually executing it?
For Rails 3:
Check out the ActiveRecord::Relation docs at the Rails 3 docs.
# get the relationrel = User.complex_scope.chained_complex_scope# get the SQL# this does not execute the querysql = rel.to_sql# find out how many records# this executes the query behind the scenescount = rel.size
It seems thatm in Rails 2.x, a private method called ActiveRecord::Base#construct_finder_sql
could be used, I need to test it more and see whether it will work for me:
ActionType.find(:all, :select => 'hosted, top_action_type, count(*) as count', :group => 'hosted, top_action_type').count#=> 6sql = 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
I know the question asks "without executing it", but the #explain
method is super useful and should at least be mentioned here. It is extremely useful for debugging slow queries.
Note: It does execute the query though.
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)