Rails模型有两个多态的has_many到:对象标记的关联

dj.*_*dj. 6 tagging activerecord ruby-on-rails has-many-through polymorphic-associations

我的架构中有ArticlesJournals可与被标记Tags.这需要has_many through:与我的Tagging连接表的多态关系关联.

好的,这是一个简单且记录良好的部分.

我的问题是Articles可以同时拥有主标签和子标签.主要标签是我最感兴趣的,但我的模型也需要跟踪这些子标签.子标签只是描述Article不太重要的标签,但来自同一个全局池Tags.(事实上​​,一个Article人的主要标签可能是另一个人的子标签).

实现这一点需要Article模型与模型有两个关联,Tagging并且两个has_many through:关联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
Run Code Online (Sandbox Code Playgroud)

我知道,在某个地方有我需要找到正确的组合sourcesource_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
Run Code Online (Sandbox Code Playgroud)

在此先感谢任何有关实现这一目标的帮助.主要问题是我无法弄清楚如何告诉Rails source_type用于Article中的sub_tags关联.

dj.*_*dj. 10

嗯...再次沉默......?什么给了SO?你好...?Bueller?

永远不要害怕,这是答案:

在研究单表继承(不是答案,但是对于其他轻微相关问题的有趣技术)之后,我偶然发现了一个关于同一模型上多态关联的多重引用的SO问题.(谢谢你hakunin的详细解答,+ 1.)

基本上我们需要taggable_typeTaggings表中为sub_taggings关联明确定义列的内容,而不是使用sourcesource_type而不是:conditions.

下面Article显示的模型现在通过了所有测试:

 class Article < ActiveRecord::Base
   has_many :taggings, as: :taggable
   has_many :tags, through: :taggings, uniq: true, dependent: :destroy

   has_many :sub_taggings, as: :taggable, class_name: 'Tagging',
             conditions: {taggable_type: 'article_sub_tag'},
             dependent: :destroy
   has_many :sub_tags, through: :sub_taggings, class_name: 'Tag',
             source: :tag, uniq: true
 end
Run Code Online (Sandbox Code Playgroud)

更新:

这是Tag在Tags上产生功能反向多态关联的正确模型.反向关联(即Tag.articles和Tag.sub_tagged_articles)通过测试.

 class Tag < ActiveRecord::Base
   has_many :articles, through: :taggings, source: :taggable,
             source_type: "Article"
   has_many :sub_tagged_articles, through: :taggings, source: :taggable,
             source_type: "Article_sub_tag", class_name: "Article"
 end
Run Code Online (Sandbox Code Playgroud)

我还扩展并成功测试了模式,以允许使用相同的Tag模型和Tagging连接表对其他模型进行标记和子标记.希望这有助于某人.