Activerecord Query Generation

Is there a way to just retrieve the sql that would be generated by an activerecord call without actually executing the call?

Umm, sort of, but it's almost certainly not what you were hoping for.

ActiveRecord generates the SQL it uses with a method called construct_finder_sql(). That method is private, and it takes a hash of options. The tricky thing is that the options can be put together by any one of many execution paths depending upon how find() was called and what was passed into it, and you sort of have to have a bit of knowledge as to how ActiveRecord translates some of the symbols you can pass to it.

For example, say you have a User model, and you want to know what User.find(:first) translates to in SQL. In order to find out, you need to know that when ActiveRecord sees :first, it translates this into an entry in the options hash of ":limit => 1". So, if you want to know what the SQL looks like for User.find(:first), what you really have to do in your console (for demonstration purposes) is this:

User.send(:construct_finder_sql, {:limit => 1})

When I do that, I get back this:

=> "SELECT * FROM users LIMIT 1"

And there is the SQL ActiveRecord would have used to perform User.find(:first). Using 'User.send(:construct_finder_sql)' sidesteps the fact that that method is private. If I tried to call it directly, I'd get an error.

One more example - how does AR execute User.find(1)? Well, I have to know that the '1' argument causes AR to set {:conditions => 'users.`id` = 1'} in it's options hash, and knowing this:

User.send(:construct_finder_sql, {:conditions => 'users.`id` = 1'})

=> "SELECT * FROM users WHERE (users.`id` = 1) "

So I think the answer to your question is, yes, there is a way - unfortunately it's not a really straightforward one, and it requires a good deal of detective work. By the time you figure out what to pass into construct_finder_sql, you've practically answered the question of what the SQL looks like anyways, so doing this may be of limited usefulness.

Maybe someone else knows of an easier way, but I don't know what it might be.

-Bill Kocik