Rails Console находит пользователей по массиву идентификаторов

Итак, у меня есть массив идентификаторов пользователей. Есть ли способ в консоли rails запросить всех этих пользователей с массивом

что-то вроде

ids = [1, 2, 3, 4]

users = User.find(ids)

и вернуть все 4 пользователя?


person Seth    schedule 29.01.2014    source источник
comment
Это действительно работает. Вы можете передать массив идентификаторов методу find модели, и, при условии, что все они являются существующими идентификаторами, вы получите обратно массив пользователей для этих идентификаторов.   -  person DiegoSalazar    schedule 29.01.2014
comment
Не понял, что это сработало ... ха-ха. Надо было это проверить.   -  person Seth    schedule 29.01.2014


Ответы (6)


Для массива вы можете использовать один из них:

# Will raise exception if any value not found
User.find( [1,3,5] )

# Will not raise an exception
User.find_all_by_id( [1,3,5] ) # Rails 3
User.where(id: [1,3,5])        # Rails 4

Если вы используете диапазон, вы можете использовать их:

# Will raise exception if any value not found
User.find((1..4).to_a)   #same as User.find([1,2,3,4])

# Will not raise an exception
User.find_all_by_id(1..4)  # Rails 3
User.where(id: 1..4)       # Rails 4

Как отмечает @ diego.greyrobot в комментарии, диапазон вызывает предложение SQL BETWEEN, тогда как массив вызывает предложение SQL IN.

Не использовать User.find_by_id() - он вернет только одну запись, независимо от того, какие идентификаторы вы передадите.

person Grant Birchmeier    schedule 29.01.2014
comment
Мой фактический массив не от 1 до 4. Идентификаторы случайны, например 122, 323, 451. Могу ли я добиться этого? - person Seth; 29.01.2014
comment
Здесь есть несколько неточностей: User.find ((1..4) .to_a) заставит его работать. И: 1..4 создает диапазон, а не массив. - person DiegoSalazar; 29.01.2014
comment
Да, важно отметить, что при передаче диапазона (User.find_all_by_id (1..4)) выполняется предложение sql BETWEEN, тогда как при передаче массива выполняется оператор sql IN. - person DiegoSalazar; 29.01.2014
comment
Отредактировано для добавления предпочтительных версий Rails 4. - person Grant Birchmeier; 20.03.2015
comment
Примечание. Дублирование и порядок игнорируются. Я использую хеш, чтобы сохранить и то, и другое: ids = [3, 3, 1, 0, 3]; Model.find(ids).map(:id) == [0, 1, 3]; h = Model.find(ids.uniq).map{|o| [o.id, o]}.to_h; h.values_at(ids).map(:id) == [3, 3, 1, 0, 3] - person Kanat Bolazar; 29.10.2015
comment
Приводит ли find к where к одному и тому же запросу sql? - person trigun0x2; 08.11.2015

вы можете использовать User.where(id: ids)

person Nitin Jain    schedule 29.01.2014
comment
В Rails 4 find_all_by_id устарел, поэтому используйте where. - person swilliams; 31.07.2014
comment
А в rails 5 он, похоже, вообще не работает, поэтому обязательно используйте User.where(id: [1,2,3,4]) - person Obromios; 09.02.2017

Используйте оператор splash:

ids = [1, 2, 3, 4]

users = User.find(*ids)

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

person BroiSatse    schedule 29.01.2014
comment
Ох, это здорово. Я не знал об этом. - person Grant Birchmeier; 29.01.2014
comment
Вам не нужно его разбрасывать, find просто отлично принимает массив. - person DiegoSalazar; 29.01.2014
comment
Я тоже нахожу это. Сплат ничего не делает. - person Grant Birchmeier; 29.01.2014

Это работа для меня ...

ids = [1, 2, 3, 4]

users = User.find(ids)

users = User.find(*ids)

users = User.find_all_by_id(ids)

Все работают ..

person Dheer    schedule 29.01.2014

вы можете использовать

   Users.where({ id: [1,2,3 ,4]})
 # SELECT * FROM users WHERE id IN (1,2,3,4)
person Tarek Saied    schedule 22.09.2014
comment
Я бы посоветовал вам расширить этот ответ, чтобы дать некоторое объяснение. Ответ, представляющий собой весь код, на самом деле не предоставляет много информации другим пользователям, которые не знакомы с концепциями в вопросе. - person psubsee2003; 23.09.2014

То, что вы делаете, должно работать, когда существуют все идентификаторы.

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

Вместо этого вы хотите использовать find_all_by_id, если не хотите получать исключение:

User.find_all_by_id([1, 2, 3, 4])

# Does the following sql:    
User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` IN (1, 2, 3, 4)
person Abdo    schedule 29.01.2014