2016-12-21 8 views
1
def has_name? name 
    results = auths.map do |auth| 
       auth.role_groups.map do |role_group| 
        role_group.resources.any?{ |r| r.name == name} 
       end 
       end 
    results.any? 
    end 

Dies ist ein Verfahren, bei User-Modell
1 Benutzer viele auths
1 Auth viele role_groups
1 role_group hat viele Ressourcen
Rails: Kann ich zwei verschachtelte Karten verwenden?

habe ich zwei Karte da, aber es Ergebnisse hat nicht zurück Ich erwarte. Dies ist das erste Mal, dass ich zwei verschachtelte Karte, kann ich es so verwenden?

+0

können Sie, aber welches Ergebnis erwarten Sie? – Ilya

+0

@llya Ich erwarte Rückkehr Ressourcen welche resource.name == Name zu Ergebnissen. Überprüfen Sie anschließend, ob das Ergebnis-Array nach results.any leer ist. –

+0

@MarcoSong: Bitte addieren Sie, was Ihr erwartetes Ergebnis ist. Es hilft Ihnen, Ihre Frage besser zu verstehen. –

Antwort

2

Sie können, aber das Ergebnis wird Array Array haben und es gilt nicht als leer.

[[]].any? 
=> true 

#flat_map könnte Ihnen helfen hier

def has_name? name 
    results = auths.flat_map do |auth| 
    auth.role_groups.map do |role_group| 
     role_group.resources.any?{ |r| r.name == name} 
    end 
    end 

    results.any? 
end 

Oder Sie könnten Ihre Lösung zusammen mit SQL-mehr performant ein ändern (ohne Ihre Modelle zu sehen, nicht sicher, ob es funktionieren wird)

auths.joins(role_groups: :resources).where(resources: { name: name }).exists? 
+0

Hey, danke! Ich weiß nicht, warum Ihre erste Lösung immer noch nicht den erwarteten Wert zurückgibt, aber Ihre zweite Lösung hat es getan. Dies ist das erste Mal, dass ich sehe, dass Leute sql query in model verwenden. Fantastisch .. –

+0

Wissen Sie, warum die erste flat_map-Lösung nicht funktioniert? Es sollte True zurückgeben, denn es gibt einen Wert im Array, aber es gibt falsch –

+0

@MarcoSong gut, nicht wirklich, sollte gut funktionieren. Überprüfen Sie es einfach vor Ort. Welche Werte befinden sich im Array "Ergebnisse"? –

0

Erstens können Sie eine direkte Beziehung zwischen auth und resources hinzufügen. Im Auth Modell: has_many: resources, through: role_groups

die hat-viele-Beziehung durch auch verschachtelt verwendet werden kann, für die hat-viele-Beziehungen (wie in Ihrem Fall). Schauen Sie sich das letzte Beispiel (Dokument, Abschnitt, Absatz Beziehungen) in hier: http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

Dann können Sie wie folgt vorgehen:

def has_name? name 
    auths.includes(:resources).flat_map(&:resources).any? do |resource| 
    resource.name == name 
    end 
end 
Verwandte Themen