好的,这是一个简单且记录良好的部分.
我的问题是文章可以同时包含主标签和子标签.主要标签是我最感兴趣的,但我的模型也需要跟踪这些子标签.子标签只是描述文章的标签,它们的重要性较低,但来自相同的全局标签池. (事实上,一篇文章的主要标签可能是另一篇的子标签).
实现这一点需要Article模型与Tagging模型有两个关联,并且两个has_many通过:与Tags的关联(即#tags& #sub-tags)
这是我到目前为止所做的,虽然有效但不保持主标签和子标签分开.
class Article < ActiveRecord::Base has_many :taggings,as: :taggable has_many :tags,through: :taggings has_many :sub_taggings,as: :taggable,class_name: 'Tagging',source_type: 'article_sub' has_many :sub_tags,through: :sub_taggings,class_name: 'Tag',source: :tag end class Tagging < ActiveRecord::Base # id :integer # taggable_id :integer # taggable_type :string(255) # tag_id :integer belongs_to :tag belongs_to :taggable,:polymorphic => true end class Tag < ActiveRecord::Base has_many :taggings end
我知道在那里的某个地方我需要找到source和source_type的正确组合,但我无法解决它.
为了完整性,这里是我用来测试它的article_spec.rb – 目前在“错误的标签”上失败了.
describe "referencing tags" do before do @article.tags << Tag.find_or_create_by_name("test") @article.tags << Tag.find_or_create_by_name("abd") @article.sub_tags << Tag.find_or_create_by_name("test2") @article.sub_tags << Tag.find_or_create_by_name("abd") end describe "the correct tags" do its(:tags) { should include Tag.find_by_name("test") } its(:tags) { should include Tag.find_by_name("abd") } its(:sub_tags) { should include Tag.find_by_name("abd") } its(:sub_tags) { should include Tag.find_by_name("test2") } end describe "the incorrect tags" do its(:tags) { should_not include Tag.find_by_name("test2") } its(:sub_tags) { should_not include Tag.find_by_name("test") } end end
在此先感谢任何有关实现这一目标的帮助.主要问题是我无法弄清楚如何告诉Rails source_type用于Article中的sub_tags关联.
解决方法
永远不要害怕,这是答案:
在查看了Single Table Inheritance(不是答案,但是对于其他轻微相关问题的一种有趣的技术)之后,我偶然发现了一个关于在同一模型上多重引用多态关联的SO问题. (谢谢hakunin为你的detailed answer,1.)
基本上我们需要在Taggings表中为sub_taggings关联显式定义taggable_type列的内容,而不是使用source或source_type,而不是:conditions.
class Article < ActiveRecord::Base has_many :taggings,as: :taggable has_many :tags,through: :taggings,uniq: true,dependent: :destroy has_many :sub_taggings,conditions: {taggable_type: 'article_sub_tag'},dependent: :destroy has_many :sub_tags,source: :tag,uniq: true end
更新:
这是正确的Tag模型,可在Tags上生成功能反向多态关联.反向关联(即Tag.articles和Tag.sub_tagged_articles)通过测试.
class Tag < ActiveRecord::Base has_many :articles,source: :taggable,source_type: "Article" has_many :sub_tagged_articles,source_type: "Article_sub_tag",class_name: "Article" end
我还扩展并成功测试了模式以允许标记和使用相同的Tag模型和Tagging连接表对其他模型进行sub_tagging.希望这有助于某人.