【问题标题】:Rails model with two polymorphic has_many through: associations for object taggingRails 模型通过两个多态has_many:对象标记的关联
【发布时间】:2013-03-28 19:18:36
【问题描述】:

我的架构有ArticlesJournals,可以用Tags 标记。这需要一个与我的Tagging 连接表具有多态关系的has_many through: 关联。

好的,这是简单且有据可查的部分。

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

实现这一点需要Article 模型与Tagging 模型有两个关联,以及与Tags 有两个has_many through: 关联(即#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 用于 Articles 中 sub_tags 关联的 source_type。

【问题讨论】:

    标签: ruby-on-rails activerecord has-many-through polymorphic-associations tagging


    【解决方案1】:

    嗯……再次沉默……?什么给了SO?你好...?比勒?

    别害怕,答案就是:

    在查看了Single Table Inheritance不是答案,而是解决其他稍微相关的问题的一种有趣技术)之后,我偶然发现了一个关于对同一多态关联的多重引用的 SO 问题模型。 (感谢 hakunin 的detailed answer,+1。)

    基本上,我们需要为sub_taggings 关联显式定义Taggings 表中taggable_type 列的内容,但不能使用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
    

    更新:

    这是正确的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
    

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

    【讨论】:

    • 来这里是为了寻找另一个问题的答案,但如此彻底回答的问题肯定值得一票(如果你自己解决了更是如此)。
    • 感谢迈克尔/在这些疯狂的时期倍加感激!该解决方案在 7 年多后的生产中仍然很强大。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    • 2014-12-16
    • 1970-01-01
    • 2023-04-03
    • 2014-12-12
    • 2016-05-13
    相关资源
    最近更新 更多