6

私のスキーマにはArticlesJournalsでタグ付けできますTags。これには、結合テーブルhas_many through:へのポリモーフィックな関係との関連付けが必要です。Tagging

さて、それは簡単でよく文書化された部分です。

私の問題はArticles、プライマリ タグとサブタグの両方を持つことができることです。私が最も関心を持っているのはプライマリ タグですが、モデルはこれらのサブ タグも追跡する必要があります。サブタグはArticle、重要度の低い を説明する単なるラベルですが、 の同じグローバル プールから取得されますTags。(実際には、1 つArticleのプライマリ タグが別のサブタグである可能性があります)。

これを実現するには、Articleモデルにモデルへの 2 つの関連付けと、Taggingモデルへの 2 つの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

そこのどこかで と の適切な組み合わせを見つける必要があることはわかっていますが、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

これを達成するための助けを前もって感謝します。主な問題は、Articles の sub_tags 関連付けに使用する source_type を Rails に伝える方法がわからないことです。

4

1 に答える 1