I don’t think it makes sense to add to change how the existing where in ActiveRecord::QueryMethods works for this case.
Either you can construct one or more queries in SQL or you can’t. If you can, you can pass in parameters like I mentioned, which seem to answer your original question, so I’m really confused at why you don’t want to solve it that way.
The way you proposed doesn’t work
1.9.3p392 :004 > Phone.where(‘(ddd, number) in ((?),(?))’, 31,32310512,31,96438112)
ActiveRecord::PreparedStatementInvalid: wrong number of bind variables (4 for 2) in: (ddd, number) in ((?),(?))
and even if it did it wouldn’t be very pretty to write. One of the good reasons to use the construct I propose is because the list could have variable number of phones. In order to support that with your solution one would have to write code for matching the number of (?) with the number of elements on the list.
Since it is unclear how what you are suggesting would be backwards compatible and generally useful for all DBs that Rails supports internally, I think you should take this question to StackOverflow or Ruby on Rails: Talk group/list to get advice.
I have already asked on StackOverflow a while back, but nobody knows the answer (Rails: Multiple or conditions in ActiveRecord - Stack Overflow). The change would be backwards compatible because it already breaks for every DBMS rails support. So, making it work for them would not break anyone’s code out there (unless it was already broken). It wouldn’t be useful to all DBs, because some wouldn’t be able to cope with tuples. However, the change is only an extension of how the prepared statement work, not a substitution of any kind of useful behavior. The way it expands lists of lists right now is not useful in any DBMS. If it became useful in a few, yet highly used, DBMS, then I would count that as a win.
Maybe I have failed to be clear so far. This is phones schema:
create_table “phones”, :force => true do |t|
t.string “ddd”
t.string “number”
t.integer “lawyer_id”
t.datetime “created_at”, :null => false
t.datetime “updated_at”, :null => false
end
add_index “phones”, [“ddd”, “number”], :name => “index_phones_on_ddd_and_number”
add_index “phones”, [“ddd”], :name => “index_phones_on_ddd”
add_index “phones”, [“lawyer_id”], :name => “index_phones_on_lawyer_id”
add_index “phones”, [“number”], :name => “index_phones_on_number”
There’s a part of my system where the user gives me a list of phone numbers and I want to check if any of them are already in the database. ddd is how area code is called in Brazil.
I hope I made things clearer now.
And, I’d hope you wouldn’t have to keep adding queries like that. That doesn’t look very efficient.
As far as I know, that is the only solution to the problem right now that doesn’t involve not using string interpolation. That’s why I think this is an issue with how ActiveRecord works now. I also think the solution I proposed is reasonable, but, of course, I’m no rails developer or anything. I’d be happy if you tell me that there’s a way to do it right now that doesn’t involve string interpolation (and hopefully no string manipulation of any kind) or doing multiple queries.