1

我有一个标签系统,可以适用于各种Taggables。我希望能够透明地查询它们,就像这里接受的解决方案一样:

HABTM 多态关系

例如,我希望能够告诉我所有标记为“foo”的Posts、Pages、Videos 等。相当直截了当。并发症:

  1. 不同种类的Taggables 在 OO 意义上不是多态的,只是通过多态关联。有一张表可以保证 taggable_id (中的主键等)的唯一性。taggablesposts
  2. 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

问题:

  1. 我想我的第一个问题应该是:这甚至可能吗?我已经看到模型“具有许多”多态关联实例,但我不确定它是否以其他方式工作,因为下面的错误消息可能暗示......
  2. 我是否正确设置了多态性?我的理解是,“子”模型基本上将自己声明为“标记”,并且直接与它们交互的表(在这种情况下map_tags)是获得:polymorphic声明的表。
  3. 如何在 ActiveRecord-speak 中说“给我展示所有标有 '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'.
...

编辑

我找到了这篇文章,其中指出我需要指定:sourceand :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

1

您的多态关联设置是正确的。除了一个小错字:

belongs_to :tagged, :polymorphic => :true

布尔值应该是真的,而不是符号:真!

于 2013-07-09T07:17:19.820 回答