Rails 3 / Ruby: метод ActiveRecord Find в условии IN Array to Parameters одиночная кавычка - PullRequest
30 голосов
/ 09 августа 2011

Я создал метод на модели микросообщений, который принимает массив user_ids.В этом методе я использую следующий метод 'find', чтобы получить все сообщения для всех пользователей в массиве.

find(:all, :conditions => ["user_id IN (?)", args.join(',')])

Но когда ActiveRecord генерирует SQL для этого запроса, он заключает список идентификаторов, разделенных запятой, в одинарные кавычки.Это приводит к тому, что запрос извлекает сообщения только для первого числа в одинарных кавычках, а не для всех чисел.

SELECT `microposts`.* FROM `microposts` WHERE (user_id IN ('3,4,5')) ORDER BY microposts.created_at DESC

Запрос должен выглядеть так, чтобы он работал правильно, но я не могу понять, как заставить Ruby преобразовать массив в список с разделителями-запятыми без кавычек, я знаю, что это должно быть что-то простоеи я просто скучаю по нему и не могу найти что-либо в Google, чтобы это исправить.Все записи, которые я нашел, используют один и тот же метод .join (',') для согласования массива.

SELECT `microposts`.* FROM `microposts` WHERE (user_id IN (3,4,5)) ORDER BY microposts.created_at DESC

Еще один факт, который может помочь вам разобраться в моей проблеме, - это массив идентификаторов, которые я передаю в метод, строится следующим образом.Не уверен, что это повлияет на ситуацию.

ids = Array.new
ids.push(current_user.id)
ids = ids + current_user.friends.map(&:id)
ids = ids + current_user.reverse_friends.map(&:id)

Заранее спасибо тому, кто может помочь мне вернуться к работе;)

Ответы [ 2 ]

72 голосов
/ 09 августа 2011

Ответ обновлен (дважды) для отражения синтаксиса Rails 3+ ActiveRecord

Rails 3 +

Вы можете использовать следующий синтаксис:

Post.where(user_id: [1,2,3])

И, таким образом:

Post.where(user_id: args)

Rails 3 или Rails 4 (оригинал)

Для полноты синтаксис Rails 3 будет иметь вид:

Post.where("user_id IN (?)", [1,2,3]).to_a

Если аргумент равенArray, затем:

Post.where("user_id IN (?)", args).to_a

Или, если args - массив строк:

Post.where("user_id IN (?)", args.map(&:to_i)).to_a

to_a является необязательным, но возвращает результаты в виде массива,Надеюсь, это поможет.

Rails 2

Вы можете просто передать массив в качестве параметра, как показано ниже:

find(:all, :conditions => ["user_id IN (?)", [1,2,3] ] )

Таким образом, если args являетсямассив идентификаторов, вы должны просто позвонить:

find(:all, :conditions => ["user_id IN (?)", args ] )

Если у вас есть проблемы с типами, вы можете сделать:

find(:all, :conditions => ["user_id IN (?)", args.map { |v| v.to_i } ] )

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

20 голосов
/ 01 февраля 2014

В рельсах 3 и 4 вы также можете просто передать массив в качестве аргумента следующим образом:

Post.where(:user_id => [1,2,3])

И это даст вам тот же результат, что и

Post.where("user_id IN (?)", [1,2,3])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...