У меня уже есть рабочее решение, но мне бы очень хотелось узнать, почему это не работает:
ratings = Model.select(:rating).uniq
ratings.each { |r| puts r.rating }
Он выбирает, но не печатает уникальные значения, он печатает все значения, включая дубликаты. И это в документации: http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields
ruby-on-rails
activerecord
alexandrecosta
источник
источник
Ответы:
Результатом этого является коллекция
Model
объектов. Непонятные рейтинги. Иuniq
с точки зрения России они совершенно разные. Вы можете использовать это:или это (наиболее эффективно)
Обновить
По-видимому, начиная с rails 5.0.0.1, он работает только на запросах «верхнего уровня», как описано выше. Не работает с прокси коллекций (например, отношения has_many).
В этом случае дедупликация после запроса
источник
Model.uniq.pluck(:rating)
это самый эффективный способ сделать это - генерировать SQL, который использует,SELECT DISTINCT
а не применяет.uniq
к массивуModel.uniq.pluck(:rating)
будетModel.distinct.pluck(:rating)
Model.related_records.group(:some_column).pluck(:some_column)
Если вы собираетесь использовать
Model.select
, то вы можете просто использоватьDISTINCT
, поскольку он будет возвращать только уникальные значения. Это лучше, потому что это означает, что он возвращает меньше строк и должен быть немного быстрее, чем возвращать количество строк, а затем указывать Rails выбрать уникальные значения.Конечно, это при условии, что ваша база данных понимает
DISTINCT
ключевое слово, и большинство должно.источник
Model.select("DISTINCT rating").map(&:rating)
чтобы получить массив только рейтинги.Это тоже работает.
источник
pluck
это чистый метод Rails> 3.2, который не зависит от Ruby 1.9.x См. apidock.com/rails/v3.2.1/ActiveRecord/Calculations/pluckЕсли вы хотите также выбрать дополнительные поля:
источник
select extra fields
<3 <3В этом есть преимущества не использовать строки SQL и не создавать экземпляры моделей
источник
Этот код работает как 'DISTINCT' (не как Array # uniq) начиная с rails 3.2
источник
источник
.pluck(:rating)
в конце сделает это именно тем, о чем просил ОП.Если я иду прямо в путь, то:
Текущий запрос
возвращает массив объектов, и вы написали запрос
Uniq применяется к массиву объекта, и каждый объект имеет уникальный идентификатор. uniq выполняет свою работу правильно, потому что каждый объект в массиве uniq.
Есть много способов выбрать отличную оценку:
или
или
или
Еще одна вещь, первый и второй запрос: найти отличные данные по SQL-запросу.
Эти запросы будут рассматриваться как «Лондон» и «Лондон» одинаково, то есть они будут пренебрегать пробелом, поэтому он выберет «Лондон» один раз в результате запроса.
Третий и четвертый запрос:
поиск данных по запросу SQL и для отдельных данных применяется метод ruby uniq. эти запросы будут считать «лондон» и «лондон» разными, поэтому в результатах запроса будут выбраны «лондон» и «лондон».
Пожалуйста, для большей ясности используйте прикрепленное изображение и посмотрите «Toured / Awaiting RFP».
источник
map
&collect
являются псевдонимами для одного и того же метода, нет необходимости приводить примеры для обоих.В некоторых ответах не учитывается, что ОП хочет массив значений
Другие ответы не работают, если ваша модель имеет тысячи записей
Тем не менее, я думаю, что хороший ответ:
Потому что сначала вы генерируете массив Model (с уменьшенным размером из-за выбора), затем вы извлекаете единственный атрибут, который имеют эти выбранные модели (оценки)
источник
Если кто-то ищет то же самое с Mongoid, то есть
источник
Другой способ собрать столбцы uniq с помощью sql:
источник