Taggable
さまざまなsに適用できるタグ システムがあります。ここで受け入れられているソリューションのように、それらを透過的にクエリできるようにしたい:
たとえば、 「foo」でタグ付けされたすべてPost
の s、Page
s、 s などを表示できるようにしたいと考えています。Video
かなり簡単です。合併症:
- さまざまな種類
Taggable
の は、OO の意味では多形的ではなく、多形的な関連付けによってのみ異なります。taggable_id ( の主キーなど)の一意性を保証するテーブルがあります。taggables
posts
Tag
s は 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
質問:
- 私の最初の質問はこうあるべきだと思います:これは可能ですか?モデルが「多くの」関連付けられたインスタンスをポリモーフィックに持っているのを見てきましたが、以下のエラー メッセージが示すように、それが逆に機能するかどうかはわかりません...
- ポリモーフィズムを正しく設定しましたか? 私の理解では、「子」モデルは基本的に自分自身を「タグ付き」として宣言し、それらと直接インターフェースするテーブル (この場合は) が宣言
map_tags
を取得するものです。:polymorphic
- 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'.