2010-11-22 3 views
0

Ich habe 3 Modelle Benutzer, Auflistung und Nachricht. Ich möchte, dass ein authentifizierter Benutzer viele Einträge hat. Die Einträge können dann mehrere Nachrichten enthalten. Die Nachrichten sind also über das Listenmodell an den Benutzer gebunden. Ich bin in der Lage, eine Benutzerliste zu erhalten, aber nicht in der Lage, die Benutzernachrichten zu erhalten, die er durch die Auflistungen besitzt. Hier sind die Assoziationen, die ich derzeit habe.Wie greife ich auf Datensätze von einem verschachtelten Modell mit 2 Ebenen zu

class User < ActiveRecord::Base 
    has_many :listings, :dependent => :destroy 
end 
class Listing < ActiveRecord::Base 
    belongs_to :user 
    has_many :messages 
end 
class Message < ActiveRecord::Base 
    belongs_to :listing 
end 

Um eine Nachricht zu erstellen, mache ich einfach dies;

@listing = Listing.find(params[:listing_id]) 
@message = @listing.messages.build(params[:message]) 

Und bekommen die Auflistung des Benutzers ich habe dies;

@user_listings = Listing.user_listings(current_user) 

Aber die auf die Objekte des Benutzers gebunden Nachrichten immer erweist sich als schwer zu sein. Was mache ich falsch oder wie gehe ich vor? Hilfe geschätzt.

+0

Wo kommt user_listings in diese kommen? – mark

+0

markieren, das ist, weil es keine Möglichkeit gibt, die Nachrichten zu erhalten, es sei denn, Sie erhalten die Benutzerlisten. Das Nachrichtenmodell ist ein Enkel des Benutzermodells, obwohl keine direkte Verbindung zwischen den beiden Modellen besteht. –

Antwort

1

Immer noch nicht sicher, wo user_listings herkommt, aber warum das nicht:

@user = User.find(params[:user_id], :include => {:listings => :messages}) 

@user.listings.each do |listing| 
    listing.messages.each do |message| 

#or 

@user.listings.collect(&:messages).each do |message| 

#or (just read about using authenticated user so the same as above like this 

current_user.listings(:all, :include => :messages)... 

Fügen Vorausabrufungen die alle Listings' zugehörigen Meldungen in einer Abfrage, damit sie in die nicht abgeholt sind Schleife verursacht n + 1 Abfrage.

---------- 

Oder ein anderer Ansatz, wenn Sie die Auflistungsdaten nicht benötigen.

#messages.rb 

    def self.user_messages user_id 
    find(:all, :joins => :listings, :conditions => ["listings.user_id = ?", user_id]) 

    #with pagination 

    def self.user_messages user_id, page 
    paginate(:all, :joins => :listings, 
        :conditions => ["listings.user_id = ?", user_id], 
        :per_page => 10, :page => page) 
+0

Danksagung, das war sehr hilfreich und ja, Sie haben Recht, ich brauche user_listings nicht. –

+0

Gern geschehen. Hinweis: Ich habe eine Korrektur für die Join-Demonstration vorgenommen, um sie zu einer Klassenmethode und nicht zu einer Instanz zu machen (self.user_m ...). – mark

0

aktualisiert in Bezug auf Ihren Kommentar.

Sie möchten möglicherweise auch has_many: messages zur Benutzerklasse hinzufügen und eine Spalte user_id zu Message hinzufügen. Dann könnten Sie gerade tun current_user.messages

+0

Danke re5et aber das ist nicht wirklich was ich will. Das bedeutet, dass Nachrichten an nur 1 Listing gebunden sind. Ich möchte, dass alle Nachrichten mit allen Listen verknüpft werden, die diesem Benutzer gehören. –

+0

aktualisierte Antwort. – re5et

+0

re5et, würde dies es überflüssig machen, dass sowohl Listing als auch Message eine Benutzer-ID haben. –

0

Wie wäre es etwa so:

class User < ActiveRecord::Base 
    has_many :listings, :dependent => :destroy 
    has_many :listing_messages, :through => :listings 

Auf diese Weise müssen Sie nicht auf die Nachrichten mit dem Benutzer „binden“, weil es immer durch die Auflistung Verein zugegriffen wird:

current_user.listing_messages.all 

Oder habe ich Ihre Frage missverstanden?

0

Wenn Sie current_user bereits gezogen haben. Sie können Inserate nur direkt zugreifen, indem

current_user.listings Aufruf

statt

@user_listings = Listing.user_listings (current_user)

Verwandte Themen