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)
Заранее благодарим того, кто может помочь мне вернуться на работу;)
Ответы
Ответ 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])