:finder_sql – single vs double quotes

This is the trickiest part of Rails I came across so far:
In my has_many association I have a finder_sql that should reference the instance object id rather than the class object id.

has_many :breedtypes, :finder_sql => 'SELECT Breedtype.* FROM ... WHERE (cai = #{id})'

Now, who’d ever have thought that replacing the “double” quotes I had wrapping the “Select” statement, would change the context from which id is interpreted.

Single Quotes -> #{id} = Object ID
Double Quotes -> #{id} = Class ID

Here’s the quote that saved the day from Jeremy (on http://lists.rubyonrails.org/pipermail/rails/2005-February/002752.html)

When you use “double quotes” the string is interpolated immediately in Project class. When you use ‘single quotes’ the string is interpolated by Rails in the context of a Project instance. Use single quotes & you’re good to go.

Phew!

Maybe I’m all hopped up goofballs, or maybe my solution is irrelevant to the context of your syntax usage, but… Can you avoid quoting issues all together in SQL queries via bind vars?

i.e.

has_many :breedtypes, :finder_sql => [“SELECT Breedtype.* FROM … WHERE (cai = ?)”, id]

Not only does this avoid quoting issues, but it will also handle not quoting integer fields, and will eliminate the possibility of a hot SQL injection ruining the show.

My two pennies…

The issue was to get the appropriate id in the has_many class method. Instance object id was the required id (not the class object id). Using the double quotes did the trick.