通过连接表删除记录

时间:2018-02-08 12:20:09

标签: ruby-on-rails ruby activerecord

我确信这已经被回答了数百次,但我今天早上已经搜索并尝试了100件事,所以我只是想问这个问题。随意将我链接到另一个帖子......

我有3个模型:Notes,Tags,NoteTags(join)

注释有很多标签,标签有很多注释;我试图销毁一个Note,NoteTag链接正在销毁,但标签仍然存在。

型号:

class Note < ApplicationRecord
  has_many :note_tags
  has_many :tags, -> { uniq }, through: :note_tags, dependent: :destroy
end

class Tag < ApplicationRecord
  has_many :note_tags
  has_many :notes, through: :note_tags, dependent: :destroy
end

class NoteTag < ApplicationRecord
  belongs_to :note
  belongs_to :tag
end

所以,显然如果Tag仍然有不同的音符,我不希望它被删除..但是如果它不再在note_tag表中显示,则应该将其删除...

有没有办法做到这一点?!

由于

1 个答案:

答案 0 :(得分:1)

你可以在销毁音符后销毁孤儿唱片。

def destroy
  @note = Note.find_by(id: params[:id])
  if @note
    @note.destroy_with_tags
  end
end

def destroy_with_tags
  oldtag_ids = tag_ids
  destroy
  Tag.find(oldtag_ids).each do |tag|
    tag.destroy if tag.notes == []
  end
end

如果标签数量很大,可能还有其他更有效的方法。

第二种方法(目前无效)

使用普通的destroy并添加一个回调来销毁孤儿标签。 此选项不起作用,但可能适用于我无法测试的一些更改。

class Note << ApplicationRecord
  before_destroy :old_tags
  after_destroy :destroy_orphan_tags

  def old_tags
    @oldtag_ids = tag_ids
  end

  def destroy_orphan_tags
    #Destroy tags that were associated to this note, if there are no more notes
    Tag.find(@oldtag_ids).joins(:note_tags).group('tags.id').having("count (*) = 0").destroy_all
  end
end