2012-04-13 4 views
0

bitte entschuldigen Sie die Rail noob Frage. Ich versuche, eine Liste der verknüpften Datensätze anzuzeigen, habe aber Schwierigkeiten, in gegensätzlichen Richtungen mit Zuordnungen umzugehen.Wie können Sie verknüpfte Datensätze über eine konvergierende Verknüpfung in Rails auflisten und einstufen?

Zum Beispiel habe ich

Country 
    has_many :states 
    has_many :users, :through => :events 
    has_many :venues, :through => :events 
    has_many :users 
    has_many :venues 
end 

State 
    belongs_to :country 
    has_many :cities 
end 

City 
    belongs_to :state 
    has_many :events 
end 

Event 
    belongs_to :city 
    belongs_to :user 
    belongs_to :venue 
end 

Venue 
    has_many :events 
    belongs_to :country 
end 

User 
    has_many :events 
    belongs_to :country 
end 

Auf dem Lande zeigen Ansicht Ich versuche, alle Ereignisse zu verzeichnen, alle Spielstätten, und alle Benutzer.

Events ist straight forward

@country = Country.find(params[:id]) 
@events = @country.states.cities.events.find(:all) 

Aber ich habe Probleme, eine beste Ansatz zu visualisieren Benutzer und Veranstaltungsorte aufzulisten.

Die Anforderungen sind:

  • Jeder einzelne Benutzer/Venue sollte ohne Duplikate einmal aufgeführt werden.
  • Benutzer/Veranstaltungsorte sollten basierend auf der Anzahl der Ereignisse bestellt werden, die sie haben haben (für das aktuelle Land, nicht insgesamt).

Dies scheint es ziemlich einfach sein sollte, aber nachdem sie mit verschiedenen Permutationen von events.includes(:user), .select("DISTINCT(ID)") spielen und .order(user.events.length) Ich habe es nicht gelungen, die Abfrage Ich brauche zu generieren.

Ich denke, ich bin wahrscheinlich in einer mentalen Furche mit diesem stecken. Ich würde wirklich einige Gedanken und Ideen von der Gemeinschaft schätzen, um zu bestätigen, ob ich auf dem richtigen Gestell bin oder nicht.

Danke!

EDIT

Nachdem ich mehr denken biss, ich glaube, mein Problem arrises von dort zwei Verbindungen zwischen Land und Benutzern, ein Verein über Ereignis ist und eine direkte Verbindung als Teil einer Adresse. Ich habe die obigen Modellbeschreibungen aktualisiert.

Als Konsequenz daraus, wie kann ich auf meiner Länderseite sicherstellen, dass ich Nutzer auflistet, die über eine Veranstaltung mit einem Land verknüpft sind, und nicht über eine Adresse?

Ich bekomme auch doppelte Benutzer. Ich habe versucht mit .uniq?, aber das gibt einen Fehler in einigen Fällen 'nil' is not an ActiveModel-compatible object that returns a valid partial path. Ich habe auch versucht mit :select => "DISTINCT(ID)", die bisher scheint eine bessere Passform. Aber was ist der Unterschied zwischen diesen beiden Ansätzen hinsichtlich ihrer Interaktion mit der Datenbank?

Antwort

3

Verwenden Sie die Option :through mit :has_many schnellen Zugriff für Ihre tief Aufzeichnungen darüber zu bekommen:

Country 
    has_many :states 
    has_many :cities, through: :states # <- 
    has_many :events, through: :cities # <- 
    has_many :users, through: :events # <- 
end 

State 
    belongs_to :country 
    has_many :cities 
    has_many :events, through: :cities # <- 
    has_many :users, through: :events # <- 
end 

City 
    belongs_to :state 
    has_many :events 
    has_many :users, through: :events # <- 
end 

Und Sie geben einfach können: @country.users.

UPD:

für alle Benutzer des Landes Ereignisse zu holen versuchen:

User.where(id: @country.events.uniq.pluck(:user_id)) 
+0

dank @jdoe, ich Ihren Vorschlag zu schätzen wissen. Mein Beispielcode oben war nicht vollständig, und ich verwende bereits durch. Nach ein bisschen mehr Nachdenken denke ich, dass ich meine Probleme auf zwei Punkte zurückverfolgt habe: (1) es gibt zwei Assoziationen zwischen meinem Land und den Benutzermodellen; (2) Ich glaube nicht, dass ich völlig verstehe, wie uniq! und wählen Sie distinct arbeiten. Ich habe meine Frage mit weiteren Details aktualisiert. Danke fürs Helfen. –

+0

Überprüfen Sie meine UPD in der Antwort. Ich nehme an, das ist was du wolltest. – jdoe

+0

Danke jdoe, das sieht vielversprechend aus. Ich werde dich wissen lassen, wie es mir geht. –

Verwandte Themen