sql >> Database teknologi >  >> RDS >> PostgreSQL

ActiveRecord:Hvordan finder man forældre, hvis ALLE børn matcher en tilstand?

Brug af arel kan få dig ret langt. Den vanskelige del er, hvordan du ikke skriver hele din forespørgsel ved hjælp af arel 's egen forespørgselssyntaks?

Her er et trick:når du bygger din forespørgsel ved hjælp af where , hvis du bruger arel betingelser, får du nogle ekstra metoder gratis. For eksempel kan du tilpasse den underforespørgsel, du har der, med .exists.not , som vil give dig en (NOT ( EXISTS (subquery))) Smid det ind i forældrenes where -klausul og du er klar.

Spørgsmålet er, hvordan du refererer til de involverede tabeller? Det skal du bruge Arel til. Du kunne brug Arels where med sine grimme forhold som a.eq b . Men hvorfor? Da det er en ligestillingsbetingelse, kan du bruge Rails' betingelser i stedet for! Du kan referere til den tabel, du forespørger på med en hash-nøgle, men for den anden tabel (i den ydre forespørgsel) kan du bruge dens arel_table . Se dette:

parents = Parent.arel_table
Parent.where(
  Child.where(other_parent_id: nil, parent_id: parents[:id]).exists.not
)

Du kan endda reducere Arel-forbruget ved at ty til strenge lidt og stole på, at du kan indlæse underforespørgsler som parametre til Rails' where . Der er ikke meget brug for det, men det tvinger dig ikke til at grave for meget i Arels metoder, så du kan bruge det trick eller andre SQL-operatorer, der tager en underforespørgsel (er der overhovedet andre?):

parents = Parent.arel_table
Parent.where('NOT EXISTS (?)',
  Child.where(parent_id: parents[:id], other_parent_id: nil)
)

De to hovedpunkter her er:

  • Du kan bygge underforespørgsler på samme måde, som du er vant til at bygge almindelige forespørgsler, ved at referere til den ydre forespørgsels tabel med Arel. Det er måske ikke engang et rigtigt bord, det kan være et alias! Skøre ting.
  • Du kan bruge underforespørgsler som parametre for Rails' where metode helt fint.


  1. Opretter en Postgresql-dump sekvenser, der starter med - eller efter - den sidste nøgle?

  2. Postgres bulk indsats/opdatering, der er injektionssikker. Måske en funktion, der tager et array?

  3. oracle Array fyldt med null-data i java

  4. MySQL Foreign Key Reference