2013-10-10 2 views
0

Я хотел бы, чтобы сформировать следующий запрос:ActiveRecord Использование Массив массивов в качестве параметров

SELECT tracked_points.* 
FROM tracked_points 
WHERE 
(id = 87 AND zone_id = 457) 
OR 
(id = 88 AND zone_id = 457) 

Мой вход функции будет вложенным массив [id, zone_id], что-то вроде:

[[87, 457], [88, 457]]

Я попробовал немного трюка я видел на сайте squeel гема

arr = [[87, 457], [88, 457]] 
TrackedPoint.where((["(id = ? AND zone_id = ?)"] * arr.size).join(" OR "), *arr) 

, но он не любит принимать вложенный массив в качестве аргумента.

Решения, которое я придумал только компилирует строку SQL, но не использует какую-либо параметры санации подготовленных заявлений:

matches = arr.map do |i| 
    "(id = #{i[0]} AND zone_id = #{i[1]})" 

TrackedPoint.where(matches.join(" OR ") 

У меня есть ощущение, ответа можно с squeel, но если есть чистый ответ ActiveRecord. Я играю, чтобы попробовать это.

  • Rails 3.2.13
  • рубин 1.9.3-p392
+0

ActiveRecord довольно ограничен для создания сложных запросов. Без каких-либо внешних надстроек, таких как squeel, я думаю, вы не будете делать ничего лучше, чем генерировать эту строку. Даже если вы найдете какой-нибудь интересный способ сделать это в SQL, вы все равно будете генерировать строку продолжения. –

+0

@EdgarsJekabsons Любая идея, как я могу добавить параметр, дезинфицирующий этот подход? –

+0

Посмотрите этот метод: http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Quoting.html#method-i-quote Я тонкий, он должен быть доступен на объекте подключения, поэтому вы должны иметь к нему доступ например: «TrackedPoint.connection.quote». –

ответ

0

Вы должны flatten вложенная массива сначала.

TrackedPoint.where((["(id = ? AND zone_id = ?)"] * arr.size).join(" OR "), *(arr.flatten)) 
Смежные вопросы