1

Taggableさまざまなsに適用できるタグ システムがあります。ここで受け入れられているソリューションのように、それらを透過的にクエリできるようにしたい:

HABTM ポリモーフィック リレーションシップ

たとえば、 「foo」でタグ付けされたすべてPostの s、Pages、 s などを表示できるようにしたいと考えています。Videoかなり簡単です。合併症:

  1. さまざまな種類Taggableの は、OO の意味では多形的ではなく、多形的な関連付けによってのみ異なります。taggable_id ( の主キーなど)の一意性を保証するテーブルがあります。taggablesposts
  2. Tags は s と多対多の関係にあり、テーブルTaggableを介して関連付けられmap_tagsます。

モデル:

class Tag < ActiveRecord::Base
  has_many :map_tags
  has_many :tagged, :through => :map_tags
end

class MapTag < ActiveRecord::Base    
  belongs_to :tags
  belongs_to :tagged, :polymorphic => :true
end

class Post < ActiveRecord::Base
  has_many :map_tags, :as => :tagged 
  has_many :tags, :through => :map_tags
  # other taggables are set up similarly
end

質問:

  1. 私の最初の質問はこうあるべきだと思います:これは可能ですか?モデルが「多くの」関連付けられたインスタンスをポリモーフィックに持っているのを見てきましたが、以下のエラー メッセージが示すように、それが逆に機能するかどうかはわかりません...
  2. ポリモーフィズムを正しく設定しましたか? 私の理解では、「子」モデルは基本的に自分自身を「タグ付き」として宣言し、それらと直接インターフェースするテーブル (この場合は) が宣言map_tagsを取得するものです。:polymorphic
  3. ActiveRecord 用語で「'foo' でタグ付けされたものをすべて見せてください」と言うにはどうすればよいですか?

私が試したこと:

irb> Tag.find_by_name( 'foo', :include => :tagged )
Tag Load (0.1ms)  SELECT `tags`.* FROM `tags` WHERE `tags`.`name` = 'foo' LIMIT 1
NameError: uninitialized constant Tag::Tagged
...
irb> Tag.find( :all, :include => :tagged, :conditions => ["Tag.name = 'foo'"] )
ActiveRecord::HasManyThroughAssociationPolymorphicSourceError:
Cannot have a has_many :through association 'Tag#tagged' on the polymorphic object 'Tagged#tagged'.
...

編集

この投稿を見つけました。これは、:sourceとを指定する必要があることを指摘しています:source_type。そう:

class Tag < ActiveRecord::Base
  has_many :map_tags
  has_many :posts, :through => :map_tags, :source => :tagged, :source_type => 'Post'
  has_many :pages, :through => :map_tags, :source => :tagged, :source_type => 'Page'
end

もっと近づいたと思いますが(?)、関連付けられたオブジェクトを照会する方法がまだわかりません...

irb> Tag.first.posts
  Tag Load (0.2ms)  SELECT `tags`.* FROM `tags` LIMIT 1
NoMethodError: undefined method `posts' for #<Tag id: 1, name: "foo">
irb> Tag.first.tagged
  Tag Load (0.2ms)  SELECT `tags`.* FROM `tags` LIMIT 1
ActiveRecord::HasManyThroughAssociationPolymorphicSourceError:
Cannot have a has_many :through association 'Tag#tagged' on the polymorphic object 'Tagged#tagged'.
4

1 に答える 1