2010-11-22 18 views
0

J'ai 3 modèles User, Listing et Message. Ce que je veux est pour un utilisateur authentifié d'avoir beaucoup de listes. Les listes peuvent alors avoir plusieurs messages. Ainsi, les messages sont liés à l'utilisateur via le modèle de liste. Je suis en mesure d'obtenir une liste d'utilisateurs, mais pas en mesure d'obtenir les messages des utilisateurs qu'il possède à travers les listes. Voici les associations que j'ai actuellement.Comment accéder aux enregistrements à partir d'un modèle imbriqué à 2 niveaux

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 

Pour créer un message, je le fais simplement;

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

et obtenir l'inscription de l'utilisateur que j'ai cela;

@user_listings = Listing.user_listings(current_user) 

Mais les messages liés obtenir aux listes de l'utilisateur ne se manifestent pas. Qu'est-ce que je fais de mal ou comment vais-je faire à ce sujet? aide appréciée.

+0

D'où vient user_listings viennent dans tout cela? – mark

+0

mark, c'est parce qu'il n'y a aucun moyen d'obtenir les messages, sauf si vous obtenez les listes des utilisateurs. Le modèle de message est un petit-enfant du modèle User, bien qu'il n'y ait pas d'association directe entre les deux modèles. –

Répondre

1

Toujours pas sûr où user_listings vient, mais pourquoi pas:

@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)... 

Inclure prélectures tous les messages associés annonces dans une requête afin qu'ils ne sont pas tiré par les cheveux dans la boucle provoquant n + 1 interrogation.

---------- 

Ou une autre approche, si vous n'avez pas besoin des données de listes.

#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

merci marque, qui a été très utile et oui vous avez raison je n'ai pas besoin de user_listings. –

+0

De rien. Remarque J'ai apporté une correction à la démonstration de jointure pour en faire une méthode de classe plutôt qu'une instance (self.user_m ...) – mark

0

mis à jour au sujet de votre commentaire.

Vous pouvez également ajouter has_many: messages à la classe d'utilisateurs et ajouter une colonne user_id à Message. Ensuite, vous pouvez simplement faire current_user.messages

+0

Merci re5et mais ce n'est pas vraiment ce que je veux. Cela signifie que les messages sont liés à une seule liste. Ce que je veux, c'est obtenir tous les messages liés à toutes les annonces appartenant à cet utilisateur. –

+0

mise à jour de la réponse. – re5et

+0

re5et, cela rendrait-il redondant à la fois pour le Listing et le Message pour avoir un identifiant d'utilisateur. –

0

Que diriez-vous quelque chose comme ceci:

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

De cette façon, vous ne devez pas « lier » les messages à l'utilisateur, car il est toujours accessible par l'association annonce:

current_user.listing_messages.all 

Ou ai-je mal compris votre question?

0

Si l'utilisateur actuel est déjà retiré. Vous pouvez simplement accéder directement en appelant annonces

current_user.listings

au lieu de

@user_listings = Listing.user_listings (current_user)