Eu já tenho uma solução funcional, mas gostaria muito de saber por que isso não funciona:
ratings = Model.select(:rating).uniq
ratings.each { |r| puts r.rating }
Ele seleciona, mas não imprime valores exclusivos, imprime todos os valores, incluindo as duplicatas. E está na documentação: http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields
ruby-on-rails
activerecord
alexandrecosta
fonte
fonte
Respostas:
O resultado disso é uma coleção de
Model
objetos. Não classificações simples. E douniq
ponto de vista, eles são completamente diferentes. Você pode usar isto:ou isso (mais eficiente)
Atualizar
Aparentemente, a partir do rails 5.0.0.1, ele funciona apenas em consultas de "nível superior", como acima. Não funciona em proxies de coleção (relações "has_many", por exemplo).
Nesse caso, desduplicar após a consulta
fonte
Model.uniq.pluck(:rating)
é a maneira mais eficiente de fazer isso - isso gera SQL que usamSELECT DISTINCT
em vez de aplicar.uniq
para uma matrizModel.uniq.pluck(:rating)
seráModel.distinct.pluck(:rating)
Model.related_records.group(:some_column).pluck(:some_column)
Se você for usar
Model.select
, poderá usar apenasDISTINCT
, pois retornará apenas os valores exclusivos. Isso é melhor porque significa que ele retorna menos linhas e deve ser um pouco mais rápido do que retornar um número de linhas e depois pedir ao Rails para escolher os valores exclusivos.Obviamente, isso é fornecido desde que o banco de dados entenda a
DISTINCT
palavra - chave e a maioria deve.fonte
Model.select("DISTINCT rating").map(&:rating)
para obter uma matriz apenas das classificações.Isso também funciona.
fonte
pluck
é um Rails puros> 3.2 método que não tem nenhuma dependência de rubi 1.9.x Veja apidock.com/rails/v3.2.1/ActiveRecord/Calculations/pluckSe você também deseja selecionar campos extras:
fonte
select extra fields
<3 <3Isso tem as vantagens de não usar seqüências de caracteres sql e não instanciar modelos
fonte
Este código funciona como 'DISTINCT' (não como Array # uniq) desde os trilhos 3.2
fonte
fonte
.pluck(:rating)
no final fará exatamente o que o OP solicitou.Se estou indo direto ao ponto, então:
Consulta atual
está retornando matriz de objeto e você escreveu uma consulta
O uniq é aplicado na matriz de objetos e cada objeto possui um ID exclusivo. O uniq está executando seu trabalho corretamente porque cada objeto na matriz é uniq.
Existem várias maneiras de selecionar classificações distintas:
ou
ou
ou
Mais uma coisa, primeira e segunda consulta: encontre dados distintos por consulta SQL.
Essas consultas serão consideradas "london" e "london" da mesma forma que serão negligenciadas no espaço; é por isso que ele selecionará 'london' uma vez no resultado da consulta.
Terceira e quarta consulta:
encontre dados por consulta SQL e para dados distintos aplicados ruby uniq mehtod. essas consultas serão consideradas "london" e "london" diferentes; é por isso que ela selecionará 'london' e 'london', ambas no resultado da consulta.
por favor, prefira a imagem anexada para obter mais compreensão e consulte "Tourou / Aguardando RFP".
fonte
map
&collect
são aliases para o mesmo método, não há necessidade de fornecer exemplos para ambos.Algumas respostas não levam em consideração que o OP deseja uma matriz de valores
Outras respostas não funcionam bem se o seu modelo tiver milhares de registros
Dito isto, acho que uma boa resposta é:
Como, primeiro, você gera uma matriz de Modelo (com tamanho diminuído por causa da seleção) e extrai o único atributo que esses modelos selecionados têm (classificações)
fonte
Se alguém está procurando o mesmo com o Mongoid, isso é
fonte
Outra maneira de coletar colunas uniq com sql:
fonte