2016-04-20 11 views
2

Ich versuche, alle Kommentare von einem bestimmten Benutzer mit user.comments zugreifen. Die Abfrage besteht darin, zwei verschiedene Modelle zu durchlaufen, die wahrscheinlich beide Ergebnisse liefern. Meine Beziehungen sind wie folgt aufgebaut:Activetrecord has_many: durch mehrere Modelle

class User < ActiveRecord::Base 
    has_many :organisers 
    has_many :participants 
    has_many :comments, through: :participants/:organisers (see explenation below) 
end 

class Organiser < ActiveRecord::Base 
    belongs_to :user 
end 

class Participant < ActiveRecord::Base 
    belongs_to :user 
end 

class Comment < ActiveRecord::Base 
    belongs_to :organiser 
    belongs_to :participant 
end 

Ein Kommentar validiert wird entweder zu einem Teilnehmer zu gehören, oder einen Veranstalter.

Ich bin mir nicht sicher, wie das geht. Ich habe versucht,

has_many :comments, through: :participants 
has_many :comments, through: :organisers 

und

has_many :comments, through: [:organisers, :participants] 

Aber das letzte ist nicht Schienen. Gibt es einen richtigen Weg, dies zu tun? Vielen Dank!

Antwort

-1

Ich glaube, Ihre Verbände verwechselt werden würden, als user.comments nicht wissen würde, ob sie durch Teilnehmer oder Veranstalter gehen, so dass die beste Option wäre zu erklären, zwei verschiedene Verknüpfungen (mit unterschiedlichen Namen):

http://guides.rubyonrails.org/association_basics.html#self-joins

+0

Stellen Sie sich diese Anfrage als 'user.participant_or_organizer_comments' vor. – steel

0

Da wir has_many, through hier nicht verwenden konnten, weil comments sowohl von organisers als auch participants stammen. Ich denke nur, es gibt 2 Lösungen hier:

Lösung 1 definieren comments Methode:

class User < ActiveRecord::Base 
    def comments 
    Comment.joins([{organiser: :user}, {participant: :user}]) 
      .where(users: {id: self.id}) 
    end 
end 

Also dann Ihre Abfrage Kommentare zu finden ist:

User.first.comments 

Lösung # 2 Verwenden Sie den Bereich in Comment

class Comment < ActiveRecord::Base 
    scope :from_user, -> (user) { 
    joins([{organiser: :user}, {participant: :user}]).where(users: {id: user.id}) 
    } 
end 

So wird Ihre Anfrage wie:

user = User.first 
comments = Comment.from_user(user) 
+0

Ich glaube nicht, dass diese Lösungen funktionieren werden, da die Joins-Anweisung effektiv als UND-Verknüpfung zwischen den beiden übergebenen Argumenten fungiert ODER'. –

0

Sie etwas tun könnte so einfach wie:

has_many :comments, -> { joins(:participant, :organizer) }, class_name: 'Comment' 

Diese sollte alle Kommentare zurück, die einen Teilnehmer oder Veranstalter Benutzer haben, da Rails neigt Standard joins zu einem inneren Join. Sie brauchen nicht einmal das Argument :class_name.

0

Ich habe nach vielen Versuchen eine Lösung gefunden. Sie können einen Bereich mit param in Ihrem letzten has_many Satz im User-Modell verwenden:

has_many :comments, -> (user) {where organiser: user.organisers}, through: :participants 

Die „user“ param represet das Benutzerobjekt denen die Kommentare Methode aufruft.