wake-up-neo.net

Wie man unterschiedliche polymorphe Assoziationen erhält

Ich versuche eine Liste polymorpher Beziehungen ohne Duplikate anzeigen zu lassen.

Ich habe eine StoreViews-Tabelle mit einem polymorphen Feld namens viewable (daher gibt es in meiner Tabelle eine viewable_id- und viewable_type-Spalte). Jetzt möchte ich Ansichten anzeigen, bei denen jede polymorphe Relation nur einmal angezeigt wird, ohne Duplikate.

@views = StoreView.
    .distinct(:viewable_id)
    .distinct(:viewable_type)
    .order("created_at DESC")
    .limit(10)

Wenn also in StoreViews zwei Datensätze vorhanden sind, die beide dieselbe sichtbare Beziehung haben, sollte @views nur den neuesten Datensatz zurückgeben. Dies ist jedoch nicht der Fall.

6
NathanB

ORDER BY-Elemente müssen in der Auswahlliste angezeigt werden, wenn SELECT DISTINCT angegeben ist. Es gibt mehrere Möglichkeiten, dieses Problem zu umgehen

In diesem Beispiel sollte die Verwendung einer Aggregatfunktion funktionieren:

@views = StoreView
           .select('DISTINCT viewable_type, viewable_id, MAX(created_at)')
           .group(:viewable_type, :viewable_id)
           .order('MAX(created_at) DESC')
           .limit(10)
6
spickermann

distinct akzeptiert nur einen Boolean als Parameter, um anzugeben, ob die Datensätze eindeutig sein sollen oder nicht. Also distinct(:viewable_id) entspricht distinct(true) und macht nicht das, was Sie wollen. Anstelle von distinct sollten Sie group verwenden, das ein Array mit unterschiedlichen Datensätzen zurückgibt, die auf dem Gruppenattribut basieren. Um den neuesten Eintrag zurückzugeben, müssen Sie die Felder in order hinzufügen, abgesehen von der Bestellung (mit group ) nach created_at:

@views = StoreView
         .order(viewable_id: :desc, viewable_type: :desc, created_at: :desc)
         .group(:viewable_id, :viewable_type)

Wenn Sie die zurückgegebenen Datensätze nach created_at bestellen müssen, müssen Sie dies hinzufügen.

ActiveRecord eindeutig:

https://apidock.com/Rails/ActiveRecord/QueryMethods/distinct

Gibt an, ob die Datensätze eindeutig sein sollen oder nicht. Zum Beispiel:

User.select(:name)
# => Might return two records with the same name

User.select(:name).distinct
# => Returns 1 record per distinct name

Wie wäre es damit:

@views = StoreView
    .select(:viewable_id, :viewable_type)
    .distinct
    .order("created_at DESC")
    .limit(10)

Sie können es auch versuchen 

@views = StoreView
    .select('DISTINCT `viewable_id`, `viewable_type`')
    .order("created_at DESC")
    .limit(10)
0
oren