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"