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

Уникальный запрос Rails 4 по одному атрибуту

Таким образом, это больше вопрос, чем что-либо, но вот что я пытаюсь сделать.

У меня есть три объекта, которые можно сказать, называемые Элементы

<Item id: 1, name: 'Book'>
<Item id: 2, name: 'Car'>
<Item id: 3, name: 'Book'>

Я хочу сделать запрос, который просто вернет только одно из каждого уникального атрибута name.

Что-то вроде Item.select('distinct(name), items.*')

Это не работает, но все равно возвращает все три элемента.

Как я могу сформировать этот запрос, чтобы он возвращался только:

<Item id: 1, name: 'Book'>
<Item id: 2, name: 'Car'>
4b9b3361

Ответ 1

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

Item.select('distinct on (name) *')

Я тестировал это только с помощью базы данных Postgres. Он может работать или не работать с mysql.

Ответ 2

Пожалуйста, попробуйте следующее:

Item.select('distinct name')

Ответ 3

В Rails 4 попробуйте Items.all.to_a.uniq { |item| item.name }

В Rails 3 вы сможете просто сделать Items.uniq_by { |item| item.name }

Когда вы вызываете uniq в массиве, вы можете передать ему блок, чтобы диктовать, как определить уникальность. В Rails 3 вы использовали возможность использовать uniq_by, но он был устаревшим в Rails 4. Таким образом, один из методов, который я нашел, - это просто преобразовать отношение ActiveRecord к массиву и вызвать uniq.

Ответ 4

Если вам нужен только массив с именами, без идентификатора, вы можете сделать:

Item.pluck(:name).uniq

Результат SQL-запроса:

#=> SELECT `items`.`name` FROM `items`

** редактировать **

uniq запускается в массиве записей. Будьте осторожны, если вы ожидаете большого количества записей. SQL Distinct намного быстрее.

Если это так, используйте vee ответ выше, с map:

Item.select('distinct name').map(:name)