6

我的架构有Articles并且Journals可以用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

我知道在那里的某个地方我需要找到正确的组合,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

提前感谢您为实现这一目标提供的任何帮助。主要问题是我不知道如何告诉 Rails 用于文章中 sub_tags 关联的 source_type。

4

1 回答 1

11

嗯……又沉默了……?什么给了SO?你好...?布勒?

不要害怕,这里是答案:

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

基本上我们需要显式定义表中taggable_type列的内容进行关联,而不是用or ,而是用。Taggingssub_taggingssourcesource_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

更新:

这是Tag在标签上产生功能性反向多态关联的正确模型。反向关联(即 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

我还扩展并成功测试了架构,以允许使用相同的标记模型和标记连接表对其他模型进行标记和子标记。希望这可以帮助某人。

于 2013-04-07T00:49:11.223 回答