Подтвердить что ты не робот

Rails 3/Ruby: ActiveRecord Метод поиска IN условие Array для параметра одиночная кавычка

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

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 преобразовывать Array в список с разделителями комы без кавычек, я знаю, что это должно быть что-то простое, и я просто пропущу его и не может найти что-либо в 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)

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

4b9b3361

Ответ 1

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

Рельсы 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

Если args является Array, то:

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

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

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

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

Рельсы 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 } ] )

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

Ответ 2

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

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

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

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