2017-12-16 4 views
-1

Mithilfe des ActsAsTaggableOn-Gems ist das Taggable-Objekt Template. Plus diese Verbände:Rails/SQL-Hilfe: drei Tabellen, Auswählen und Sortieren nach Anwesenheit eines anderen Datensatzes

class Template 
    acts_as_taggable 
    has_many :template_designs 
end 

class Pins 
    belongs_to :template 
    belongs_to :tag 
end 

class Tags 
    has_many :taggings 
end 

Ziel: eine Sammlung von Vorlagen bereit paginiert zu werden, wo der Benutzer einen Tag auswählt, finden wir alle Vorlagen dieses Tag übereinstimmt, und sortieren sie nach, ob der gleiche Tag und Vorlage existieren in Stifte mit Spuren oben.

EDIT - Vereinfachung und Paraphrasierung.

Da ein Template mit Tags getaggt ist, und diese Tags möglicherweise keinen Pin haben, muss ich alle Templates mit X-Tag auswählen und sie sortieren, ob dieses Tag einen Pin hat (boolean sort, trues on top).

+0

Bitte Beispieldaten gemeinsam nutzen, fragen Sie Ihre versucht und gewünschte Ausgabe. – zarruq

Antwort

0

Ein Ansatz ist Outer-Joins zusammen mit einem CASE WHEN EXISTS Ausdruck zu verwenden:

select templates.*, case when exists 
    (select pins.id 
    from pins 
    where pins.tag_id = tags.id 
    and pins.template_id = templates.id) then true else false end as pinned 
    from templates, taggings, tags, pins 
    where templates.id = taggings.template_id 
    and taggings.tag_id = tags.id 
    and tags.name = 'funny'; 

Hier ist ein Active Record Syntax dafür:

>> Template.left_outer_joins(:tags) 
.where(tags: {name: 'funny'}) 
.select(:id, :name, 
"case when exists 
    (select pins.id from pins 
    where pins.tag_id = tags.id 
    and pins.template_id = templates.id) 
    then true else false end as pinned") 
.map {|t| [t.id, t.name, t.pinned] } 
[... sql output ...] 
=> [[1, "template1", true], [2, "template2", false]] 
+0

Versuchte diesen Ansatz in einer Vielzahl von Möglichkeiten, hat für mich nicht geklappt. Ich habe nicht die DB angegeben, die ich benutze, nämlich Postgres, und es mag den Alias ​​für den zurückgegebenen Wert aus dem Case When nicht. Auch angewendet der Ansatz zu dieser einfacheren Abfrage und die Reihenfolge von tritt nicht ein: SELECT ID, insgesamt FROM Bestellungen ORDER BY CASE \t WENN EXISTEN (SELECT ID, insgesamt FROM Bestellungen WHERE orders.total> 100000) DANN true \t ELSE false END – bazfer

+0

Ich schaue jetzt dynamische Abfrage-Generation, um dieses lustige Problem zu lösen. Danke für die Hilfe. – bazfer

+0

@bazfer Ich bin überrascht, dass Fall/wenn Konstrukt nicht für Sie arbeitet ... Ich benutze auch Postgres (9.6), aber ich habe das Schema möglicherweise missverstanden. Ich fügte das Schema hinzu, das ich benutzte, Korrekturen willkommen. –

Verwandte Themen