2013-08-05 14 views
13

Quindi questa è più una questione arel che altro, ma ecco quello che sto cercando di fare.Rails 4 query univoca per singolo attributo

ho tre oggetti permette di dire, denominati elementi

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

voglio fare una query che sarà solo tornare solo uno di ogni "nome" unico attributi.

Qualcosa di simile Item.select('distinct(name), items.*')

Questo non funziona, però, restituisce ancora tutti e tre gli elementi.

Come faccio a formare questa query in modo che restituisce solo:

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

in modo che oggetto libro deve restituire, 1 o 3? – sevenseacat

+0

@sevenseacat non importa, o funziona. – goddamnyouryan

risposta

23

Se si desidera ottenere l'intero modello di nuovo, ma ancora mantenere l'unicità, è possibile utilizzare questo:

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

L'ho provato solo con un database Postgres. Potrebbe o potrebbe non funzionare con mysql.

+2

la risposta sopra restituirà tutte le colonne, se vuoi selezionare solo alcune colonne puoi provare con 'Item.select ('distinto su nome (nome), id')' –

+1

Questo è geniale! Ho cercato questo ovunque :-) – Abdo

+1

Sono stato fuori di testa perché mi sono reso conto che avevo bisogno di prendere solo i record più recenti su un DB, e dovevo mostrare qualcosa al mio capo ma per la vita di me couldn ottenere il lavoro fino a quando ho trovato questo. Sei un risparmiatore di vita, che tu !!! – edhog

11

Si prega di provare questo:

Item.select('distinct name') 
+5

Questo tipo di opere. Restituisce gli oggetti con solo l'attributo 'nome'. Voglio restituire l'intero oggetto.Ottengo questo: , goddamnyouryan

+0

Prova Item.select ('id', 'name') – TalkativeTree

+0

@goddamnyouryan È un po 'tardi , ma vedi la mia risposta qui sotto. – BananaNeil

2

In Rails 4 provare Items.all.to_a.uniq { |item| item.name }

In Rails 3 si dovrebbe essere in grado per fare solo Items.uniq_by { |item| item.name }

Quando si chiama uniq su un array, è possibile passarlo un blocco per stabilire come determinare l'unicità. In Rails 3 eravate in grado di usare uniq_by, ma è diventato obsoleto in Rails 4. Quindi un metodo che ho trovato è quello di convertire la relazione ActiveRecord in un array e chiamare uniq su quello.

+7

Questo è ottimo per le query di piccole dimensioni, ma prestazioni terribili per i set di dati di grandi dimensioni. – Sean

+0

Davvero una cattiva idea per '.to_a' una query che carica i dati in memoria. – bcackerman

2

Se avete solo bisogno di una matrice con i nomi, senza l'ID, si può fare:

Item.pluck(:name).uniq 

SQL risultato della query:

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

** Modifica **

Il uniq viene eseguito sull'array di record. Stai attento se ti aspetti molti record. SQL Distinct è molto più veloce.

Se è così, usano la risposta di vee sopra, con un map:

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