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%>

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 .


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


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"

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


6

Versuchen Sie dies (in der Rails-Konsole)

Product.group(:category)

Product.group(:category).each { |p| p.name }

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)


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 %>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.