4

私はRails 3.0.3アプリケーションのアクティビティフィードにそれらを統合できるように、最近のコメントを10個見つけようとしています。 commentableコメントモデルで説明されてRails:多態的な関連付けとSTIを含むクエリの構造化

class Upload < ActiveRecord::Base 
    ... 
end 

class Photo < Upload 
    has_many :comments, :as => :commentable 
    ... 
end 

ポリモーフィックな関連:

は、私は、単一テーブル継承を使用してアップロードモデルから継承し写真モデルを、持っている

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

これまでのところ、とても良いですか?問題はクエリを作成しようとするときに発生します。このコードは、SQLiteのと私の開発マシン上で動作しますが、私はそれを動作させるためにいくつかの変更を行うために持っていた

def self.latest_comments(count = 10) 
    Comment.where(:commentable_type => "Upload")\ 
     .joins("INNER JOIN uploads ON comments.commentable_id = uploads.id")\ 
     .where("uploads.type" => "Photo").order("comments.created_at DESC").limit(count) 
end 

:いくつかの試行錯誤の後、私は写真のモデルに座って、このコードを思い付いPostgreSQLを使用しているプロダクションサーバーで上記のクエリのインカネーションはまだプロダクションサーバ上でテストされていませんが、私はクエリを構造化するためのより洗練された方法を探していました。これは非常に堅牢ではなく、まったく「Railsy」にも見えません。私がしたい何

言うことができるようにすることです

Comment.joins(:commentable => :photo) 
です...しかし、これはRailsが行う方法を知っていないと思われるので、例外が発生します参加:

ActiveRecord::EagerLoadPolymorphicError: Can not eagerly load the polymorphic association :commentable

post on StackOverflowには、多態性の関連付けを照会する別の方法が記載されています。しかし、これはSTIのために動作しません

Comment.find_all_by_commentable_type("Upload", :include => :commentable, 
     :order => "created_at DESC", :limit => 10) 

:写真のアップロードから継承されているので、私は直接写真に関するコメントを取得することはできません私はこの記事に基づいて、次のコードを思い付くことができました - Uploadから継承したすべてのクラスのコメントのみ。

私は多型またはSTIのいずれかに関する多くの他の投稿を見てきましたが、探している方法で2つを組み合わせるものはありません。私はちょうど最初のクエリで混乱することができますが、誰も多形性を含むクエリを構造化する別の方法に任意の考えを持っています STI?

を編集します。another questionは私と同じ行にあります。残念ながら、トップの答えは私が探している解決策を提供していませんでした。問題にそれを適用する場合は、PhotoモデルからUploadモデルへのhas_many :commentsの関連付けを移動し、Commentクラスにいくつかのコードを追加してcommentableの正しいクラスを決定します。これは理想的ではありません。なぜなら、アップロードのサブクラスにはコメントが付いているという点でモデリングが壊れてしまうからです。より良い方法が必要でしょう...?

答えて

1

Uploadクラスのコメントへの関連付けを提供しています。アップロードを継承する写真は、継承を介してこの関連付けを行います。コメントの方法がアップロードインスタンスの両方で利用可能で、写真のインスタンス上で、あなたがコメントを取得するには、次のメソッドを書くことができますので:

# app/models/upload.rb 

def latest_comments(count=10) 
    self.comments.order("created_at DESC").limit(count) 
end 

これは、タイプ「アップロード」する場合を使用して、コメントテーブルに参加しますUploadのインスタンスで作業し、そのクラスのインスタンスで作業する場合は、「Photo」タイプを使用して結合します。 Railsは、コメントの関連付けを行うときに、クラス名を使用してコメントテーブルへの結合を自動的に処理します。

+0

返信いただきありがとうございますが、私のモデルでは、写真のみがコメントであり、アップロードはコメントできないように指定しています。これは、スーパークラスの 'Upload'に' has_many:comments'という関連付けが与えられていれば事態を大幅に簡略化しますが、これを行うことでモデルを壊したくありません。そうしたやり方でモデルを混乱させたくないのであれば、長い連鎖クエリがなくても実際に実現したいのですか? – JamesDS

関連する問題