2017-02-05 1 views
0
class Parent < ApplicationRecord 
    has_many :children 

    enum status: { 
    status1: 0, 
    status2: 1  
    } 
end 

class Child < ApplicationRecord 
    belongs_to :parent 
end 

# error 
# "Relation passed to #or must be structurally compatible. Incompatible values: [:references]" 
combination = Parent.status1.or(Parent.status2.includes(:children).where(children: {name: 'ABC'})) 

Ich möchte die Daten "Status1" oder "Status2 hat Kinder mit dem Namen 'ABC'" erhalten, aber Fehler tritt auf.【Rails5】 Wie kann ich die ActiveRecord "OR" -Abfrage mit "includes" verwenden?

Antwort

2

Die or method nimmt eine andere Beziehung, die ein ähnliches Filtermuster hat, und kombiniert es mit den bereits vorhandenen Filtern auf dem Objekt, das aufgerufen wird.

Zum Beispiel würde Parent.status1.or(Parent.status2) Ihnen eine Reihe von Datensätzen geben, die entweder status: 1 oder status: 2 haben.

(Falls jemand nicht mit ihm vertraut, das Beispiel in der Frage verwendet auch enum, das den Attributwert der ENUM-Filterung ermöglicht den Namen des Wertes verwenden. #status1 und #status2 in diesem Fall entspricht { status: 0 } und {status: 1} bzw. sie auf das Ergebnis rufen Sie müssen der Aufruf #or, wie diese)

um das Endergebnis zu modifizieren mehr Relation Methoden aufrufen.

Parent.status1.or(Parent.status2).includes(:children).where(children: {name: 'ABC'}) 

Basierend auf Ihren Kommentar, den ich sehe jetzt, dass Daten erfasst werden sollen, die entweder (haben status1) oder (haben status2und haben eine passende children Rekord).

Beachten Sie, dass, um eine Beziehung in einem verwenden where (wie where(children: { name: value }) Sie müssen beitreten mit der verknüpften Tabelle (joins(:children).where(children: { name: value }). Es scheint, dass Active wird folgern, die beitreten, wenn Sie nur includes verwenden, aber das ist nicht so weit dokumentiert ., wie ich sagen kann, Aus diesem Grund or die beiden Beziehungen als unvereinbar sieht. ein children in der Referenzliste hat, während der andere nicht

Wenn Sie die where Klausel von Hand als String schreiben, tut es nicht ändern Die Referenzliste, also or sieht die Beziehung nicht als inkompatibel eine where Klausel von Hand schreiben, müssen Sie explizit Verwendung joins:

Parent.status1.joins(:children).or(Parent.status2.joins(:children).where("children.name = 'ABC'")) 
+0

Ich habe es. Danke für deinen Rat! –

+0

Was ich tun möchte ist, dass die Daten "status1 OR (status2 AND children.name = ABC)" erhalten. So habe ich es schließlich mit dem folgenden Code versucht. 'st1_ids = Parent.status1.pluck (: id)' ' st2_and_name_is_abc_ids = Parent.status2.pluck (: id)' ' conbination = Parent.where (id: st1_ids + st2_and_name_is_abc_ids)' –

+0

Ich habe falsch verstehen Ihre Frage . Ich habe meine Antwort aktualisiert. Kann ich [diesen Artikel] (http://stackoverflow.com/help/how-to-ask) vorschlagen, wie man effektivere Fragen schreibt? Wenn Sie eine detailliertere Liste Ihrer Erwartungen hinzugefügt hätten, hätten Sie möglicherweise schneller eine bessere Antwort erhalten. –

0

Du „auch“ auf dem letzten oder Ergebnis nicht aufrufen.

parent = Parent.status1.or(Parent.status2) 
parent.includes(:chilren).where(children: {name: "ABC"}) 
Verwandte Themen