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'>
6 ответов:
Если вы хотите вернуть всю модель, но при этом сохранить уникальность, вы можете использовать следующее:
Item.select('distinct on (name) *')
Я проверил это только с базой данных Postgres. Он может работать или не работать с mysql.
Если вам нужен только массив с именами, без идентификатора, вы можете сделать:
Item.pluck(:name).uniq
Результат SQL-запроса:
#=> SELECT `items`.`name` FROM `items`
** edit * *
uniq
выполняется на массиве записей. Будьте осторожны, если вы ожидаете много записей. SQL Distinct работает намного быстрее.Если это так, используйте ответ ви выше, с
map
:
Item.select('distinct name').map(:name)
В 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
на этом.
Для Mysql вы можете использовать
group
с ONLY_FULL_GROUP_BY отключено,Item.group(:name).to_sql => "SELECT `items`.* FROM `items` GROUP BY name"