10

コードに問題がある

class Post < ActiveRecord::Base
end

class NewsArticle < Post
  has_many :comments, :as => :commentable, :dependent => :destroy, :order => 'created_at'
end

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

そして、いくつかの NewsArticle のコメントを取得しようとすると、ログに次のようなものが表示されます

  Comment Load (0.9ms)   SELECT "comments".* FROM "comments" WHERE ("comments"."commentable_id" = 1 and "comments"."commentable_type" = 'Post') ORDER BY created_at

"commentable_type" = 'Post'というのは奇妙です。どうしたの?

PS: Rails 2.3.5 && ruby​​ 1.8.7 (2010-01-10 パッチレベル 249) [i686-darwin10]

4

5 に答える 5

5

commentable_typeフィールドには、データを含むテーブルの名前を格納する必要があります。その行が右側のテーブルから読み込まれると、継承された型がPostsテーブルのtype列から読み込まれます。

そう:

ここで、コメントは、コメントするテーブルを指しています。投稿テーブル、id 1

>> Comment.first
=> #<Comment id: 1, commentable_id: 1, commentable_type: "Post", body: "test", created_at: "2010-04-09 00:56:36", updated_at: "2010-04-09 00:56:36">

次に、NewsArticle をロードするために、id 1 が投稿からロードされ、そこにあるタイプは NewsArticle を示します。

>> Comment.first.commentable
=> #<NewsArticle id: 1, type: "NewsArticle", name: "one", body: "body", created_at: "2010-04-09 00:55:35", updated_at: "2010-04-09 00:55:35">
>> Comment.first.commentable.class.table_name
=> "posts"

commentable_typeが保持されている場合"NewsArticle"、クラスを調べてテーブルを決定する必要があります。このようにして、テーブルを見て、そこに着いたら型について心配することができます。

于 2010-04-09T01:04:20.380 に答える
1

ActiveRecord::Associations APIの Polymorphic Associations セクションを見てください。単一テーブルの継承と組み合わせてポリモーフィックな関連付けを使用することについて少し説明があります。そのセクションの2番目のコード例に従うと、これはあなたが望むものに近いかもしれないと思います

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

  def commentable_type=(sType)
   super(sType.to_s.classify.constantize.base_class.to_s)
  end
end

class Post < ActiveRecord::Base
  has_many :comments, :as => :commentable, :dependent => :destroy, :order => 'created_at'
end

class NewsArticle < Post
end
于 2010-04-09T21:17:22.173 に答える
1

良い質問。Rails 3.1を使用してまったく同じ問題が発生しました。問題はまだ解決されていないようです。どうやら、Rails で単一テーブル継承 (STI) と組み合わせてポリモーフィック アソシエーションを使用するのは少し複雑です。

Rails 3.2 の現在の Rails ドキュメントでは、ポリモーフィック アソシエーションと STIの組み合わせについて次のようなアドバイスが提供されています。

ポリモーフィック アソシエーションを単一テーブル継承 (STI) と組み合わせて使用​​するのは少し注意が必要です。アソシエーションが期待どおりに機能するためには、ポリモーフィック アソシエーションのタイプ列に STI モデルの基本モデルを格納してください。

あなたの場合、基本モデルは「Post」になります。つまり、「commentable_type」はすべてのコメントに対して「Post」である必要があります。

于 2012-05-30T16:53:15.380 に答える
1

def commentable_type=(sType) super(sType.to_s.classify.constantize.base_class.to_s) end

このメソッドはクラスを Post として返していますが、継承したクラス Post を commentable_type として保存したい場合はどうすればよいですか?

于 2010-12-16T14:33:12.603 に答える
0

技術的には、実際には何も問題はありません。Railsがポリモーフィックな関連付けを扱っていて、関連付けられているオブジェクトがSTIを使用している場合、単純に基本クラスをタイプとして使用します(この場合は「commentable_type」)。

Post と NewsArticle が別々のテーブルにある場合、commentable_type はそれぞれ Post と NewsArticle として表示されます。

于 2010-09-23T12:55:49.933 に答える