Frage

Ich verwende polymorphe Assoziationen Kommentare in meinem Projekt zu verfolgen. Alle sehr geradlinig Sachen.

Das Problem, das ich habe, ist auf der Grundlage der polymorphen Vereinigung in Abfrage und aus dem Kommentar-Modell verbinden zurück zu er ist Inhaber.

So ...

Ich habe einen Kommentar Modell

class Comment < ActiveRecord::Base
  belongs_to :commentable, :polymorphic => true
end

Und ein Forumthemen-Modus:

class ForumTopic < ActiveRecord::Base
  has_many :comments, :as => :commentable
end

Ich habe mehrere andere „kommentierbaren“ Modelle, die gerade jetzt nicht wichtig sind. All dies funktioniert.

Was ich versuche, all die Kommentare zu tun ist, finden die mit einer bestimmten Bedingung zu einem ForumTopic gehören (in diesem Fall ‚gekennzeichnet‘ == true).

Wenn ich versuche, und verwenden Sie einen Finder die Modelle verbinden:

@comments = Comment.find(:all 
            :joins => :commentable
            :conditions => ["forum_topics.featured = ? ", true] 
            )

Ich erhalte den folgenden Fehler:

  

Kann nicht mit Spannung die polymorphe Vereinigung laden: kommentierbaren

Mit dem AR "umfassen Syntax":

@comments = Comment.find(:all 
            :include => :forum_topics
            :conditions => ["forum_topics.featured = ? ", true] 
            )

Rückgabe:

  

Verband namens 'forum_topics' wurde nicht gefunden; vielleicht Sie es falsch geschrieben?

Wenn ich versuche, und mit einem Tabellennamen verbinden anstelle des Vereins (String statt Symbol):

@comments = Comment.find(:all,
            :joins => "forum_topics",
            :conditions => ["forum_topics.featured = ? ", true] 
            )

Ich sehe:

  

Mysql :: Fehler: Unbekannte Tabelle 'Kommentare'. SELECT Kommentare FROM Kommentare forum_topics WHERE (forum_topics.featured = 1) *

(Sie können hier sehen, dass die Syntax der zugrundeliegenden Abfrage vollständig ausgeschaltet ist und die Verbindung fehlt insgesamt).

Nicht sicher, ob was ich tue, überhaupt möglich ist, und es gibt auch andere Möglichkeiten, um das gewünschte Ergebnis zu erreichen, aber es scheint, wie es sollte sein machbar.

Irgendwelche Ideen? Alles, was ich bin fehlt?

War es hilfreich?

Lösung

Argh!

Ich denke, dass ich das Problem gefunden.

Beim Verbinden über:

@comments = Comment.find(:all,
        :joins => "forum_topics",
        :conditions => ["forum_topics.featured = ? ", true] 
        )

Sie müssen die ganze beitreten!

:joins => "INNER JOIN forum_topics ON forum_topics.id = comments.commentable_id",

Sehen Sie die immer genial: http://guides.rubyonrails.org/active_record_querying.html#joining-tables

Andere Tipps

Eine alte Frage, aber es ist ein sauberer Weg, dies zu erreichen, indem eine direkte Verbindung für die spezifische Art zusammen mit dem polymorphen Einrichtung:

#comment.rb
class Comment < ActiveRecord::Base

  belongs_to :commentable, polymorphic: true
  belongs_to :forum_topics, -> { where( comments: { commentable_type: 'ForumTopic' } ).includes( :comments ) }, foreign_key: 'commentable_id'

  ...

end

Sie sind dann in der Lage :forum_topics passiert von der Notwendigkeit eines chaotisch includes Loswerden beitreten:

@comments = Comment
  .includes( :forum_topics )
  .where( :forum_topics => { featured: true } )

Sie könnten dann weiter diese aufzuräumen, indem die Abfrage in einem Rahmen bewegen:

#comment.rb
class Comment < ActiveRecord::Base

  ...

  scope :featured_topics, -> { 
    includes( :forum_topics )
    .where( :forum_topics => { featured: true } ) 
  }

  ...

end

Sie verlassen können einfach tun

@comments = Comment.featured_topics

Sie benötigen ein Bedingtes, Plus-Rails 3 +

Eine Menge Leute erwähnt, um es in den Antworten und Kommentare, aber ich fühlte, dass die Leute, mich eingeschlossen, würde, wenn ich hier gelandet bekommen gestolpert und nicht gründlich genug gelesen.

So, hier ist die richtige Antwort, einschließlich der Bedingung, dass ist absolut erforderlich.

@comments = Comment.joins( "INNER JOIN forum_topics ON comments.commentable_id = forum_topics.id" )
                   .where( comments:     { commentable_type: 'ForumTopic' } )
                   .where( forum_topics: { featured:         true         } )

Vielen Dank an alle, vor allem @Jits, @ Peter, und @prograils für ihre Kommentare.

Die akzeptierte Lösung funktioniert nicht, wenn Sie ein anderes Modell einführen, die eine Assoziation mit „kommentierbaren“ hat. commentable_id ist nicht eindeutig und daher werden Sie beginnen, die falschen Kommentare abgerufen werden.

Zum Beispiel:

Sie entscheiden, ein Nachrichten-Modell hinzufügen, die Kommentare akzeptiert ...

class News < ActiveRecord::Base
   has_many :comments, :as => :commentable
end

Jetzt können Sie zwei Datensätze zurück, wenn Sie einen Kommentar zu forum_topic mit der ID 1 und einem Nachrichtenartikel mit der ID 1 mit Ihrer Anfrage gemacht:

:joins => "INNER JOIN forum_topics ON forum_topics.id = comments.commentable_id"

Sie könnten wahrscheinlich das Problem zu lösen, indem ein commentable_type als eine Ihrer Bedingungen liefern, aber ich glaube nicht, das ist der beste Weg, um dieses Problem zu nähern.

Ich kam in diesem Beitrag und es mich zu meiner Lösung führen. Unter Verwendung des commentable_type als eine meiner Bedingungen, aber eine LEFT OUTER JOIN mit statt. Auf diese Weise Forum Themen ohne Kommentare werden enthalten sein.

LEFT OUTER JOIN `comments` ON `comments`.`commentable_id` = `forum_topics`.`id` AND `comments`.`commentable_type` = 'ForumTopic'

Checked unter Rails arbeiten 5 :

Lösung 1:

@comments = Comment
              .where(commentable_type: "ForumTopic")
              .joins("INNER JOIN forum_topics ON comments.commentable_id = forum_topics.id")
              .where(forum_topics: {featured: true})
              .all

oder

Lösung 2:

@comments = Comment
              .joins("INNER JOIN forum_topics ON comments.commentable_id = forum_topics.id AND comments.commentable_type = 'ForumTopic'")
              .where(forum_topics: {featured: true}).all

Achten Sie auf die Roh-SQL-Syntax: keine Backticks sind erlaubt. Siehe http://guides.rubyonrails.org/active_record_querying.html#joining-tables.

Ich persönlich bevor Lösung 1, da es weniger rohe SQL-Syntax enthält.

Schienen beinhaltet nicht eine polymorphe standardmäßig verbinden, aber dieses Juwel würde Ihnen helfen, Ihre polymorphe Beziehung mit Leichtigkeit verbindet. https://github.com/jameshuynh/polymorphic_join

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top