Schienen: Wie kann ich eindeutige Werte aus der Spalte erhalten?

73

Wie kann ich eindeutige Werte aus der Spalte in der Tabelle abrufen? Zum Beispiel habe ich diese Produkttabelle:

ID NAME CATEGORY
1 name1 1st_cat
2 name2 2nd_cat
3 name3 1st_cat

Hier möchte ich nur 2 Werte erhalten - 1st_cat und 2nd_cat:

<%Products.each do |p|%>
<%=p.category%>
<%end%>
Oleg Pasko
quelle
Sie können auch Product.group ("category_id")
gruppieren
2
Alle möglichen Möglichkeiten unten - Es sollte beachtet werden, dass Products.uniq.pluck (: Kategorie) der effizienteste Weg ist
Yo Ludke
3
Nur ein nachträglicher Gedanke; Wenn Ihre Modellnamen Plural sind, machen Sie es nach Ansicht von Rails falsch.
RCD

Antworten:

165

Zwei weitere Möglichkeiten:

Product.select(:category).map(&:category).uniq # Ruby does the work

Product.uniq.pluck(:category) # DB does the work (superior)

Für Schienen> = 5.1 verwenden Sie:

Product.distinct.pluck(:category) # DB does the work (superior)

... da Relation#uniqwar veraltet .

user664833
quelle
2
Ich habe genau danach gesucht: Products.pluck (: category) .uniq Superb! +1 :)
KM Rakibul Islam
7
Dadurch werden alle Produkte in ein Ruby-Array gezogen, anstatt die Arbeit in der Datenbank zu erledigen.
Superluminary
1
@superluminary zieht alle Produkte in ein Ruby-Array, anstatt dass die DB die empfohlene Arbeit ausführt?
8bithero
13
User.uniq.pluck(:source)produziert, SELECT DISTINCT "users"."source" FROM "users"also glaube ich nicht, dass es alle Datensätze in ein Ruby-Array lädt.
Rafael Oliveira
3
Für Rails> = 5.1 verwenden SieProducts.distinct.pluck(:category)
Davegson
26

Ich denke, Sie können dies tun:

<% Products.select("DISTINCT(CATEGORY)").each do |p| %>
<%= p.category %>
<% end %>

Quelle: http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields

ThatOtherPerson
quelle
Ich bin selbst ein Rails-Neuling (arbeite gerade an den Tutorials ;-)) Ich habe es gegoogelt.
ThatOtherPerson
funktioniert nur, wenn Sie 1 Spalte wollen, andere Spalte sind nicht ausgewählt
srghma
10

Dies erledigt die gesamte Arbeit auf dem Datenbankserver. Das Ergebnis ist ein einfaches Array.

<% Product.distinct(:category).pluck(:category).each do |category|
    <%= category %>
<% end %>

Rails generiert SQL, das in jeder Datenbank (Postgres, MySQL usw.) funktioniert.

SELECT DISTINCT "products"."category" FROM "products"
jelder
quelle
8

Ich schlage vor, zu verwenden, Products.all.distinct.pluck(:category)weil uniqseit Schienen 5 veraltet ist und es auf Schienen 5.1 entfernt wird

Fabio Ros
quelle
6

Versuchen Sie dies (in der Rails-Konsole)

Product.group(:category)

Product.group(:category).each { |p| p.name }
Marek Příhoda
quelle
5
Das wird nur auf MySQL-Datenbanken funktionieren (möglicherweise auch SQLite, aber definitiv nicht gut auf Postgres oder MSSQL
Jamesc
Arbeitet auf SQLite
Geoffrey H
Sie müssen: Product.select (: category) .group (: category), damit dies auf Postgresql (und ich denke MSSQL) funktioniert.
Ben Trewern
4

Für Postgres

<% Product.select("DISTINCT ON (category) *").each do |category|
    <%= category %>
    <%= name %>
<% end %>

Aktualisieren

noch besser

<% Product.select(%(DISTINCT ON (category) "#{Product.table_name}".*)).each do |category|
    <%= category %>
    <%= name %>
<% end %>

weil es dabei falsche Spalten zurückgeben kann joins(z. B. idSpalte aus verknüpfter Tabelle zurückgeben, aber nicht products)

Srghma
quelle
Abgestimmt, weil diese Lösung für mich funktioniert hat, wenn Sie die gesamte aktive Datensatzbeziehung anstelle des Zupffelds benötigen.
Arth Thakkar
0

Musste eine eindeutige Ausgabe erhalten und versuchte die 'uniq'-Methode erfolglos. Versuchte mehrere hier veröffentlichte Lösungen erfolglos. Ich verwende devise, mit dem ich auf die current_userMethode zugreifen und mit zwei Tabellen arbeiten kann, von denen eine ein Join ist (ein Element has_many: things).

Diese Lösung hat letztendlich bei mir funktioniert:

@current_user.things.select(:item_fk).distinct.each do |thing|
 <%= thing.item.attribute %>
<% end %>
Philish
quelle