【问题标题】:Modifying acts-as-taggable-on tags without touching/saving the tagged record在不触摸/保存标记记录的情况下修改作为可标记的标记
【发布时间】:2020-05-17 14:57:04
【问题描述】:

在进行一些重构时,我遇到了一种情况,我想更改标签名称的格式。最初,我尝试通过更改受影响的 ActsAsTaggableOn::Tag 记录的名称来简单地进行迁移,但问题是一些新的标签名称已经存在于不同的标签上下文中。

我可以找到_each 标记的对象并一一更新它们,但这很慢,我不想触摸(updated_at)记录,因为它们并没有真正改变。然后我想重命名标签,除非它存在,在这种情况下我会更新标签上的 tag_id 但我担心它会与 taggings_count 或其他东西混淆。

有没有一种方法可以轻松更改记录上的标签而无需保存记录本身?该文档仅真正包含模型扩展和查找器方法。

【问题讨论】:

    标签: ruby-on-rails acts-as-taggable-on


    【解决方案1】:

    然后我想重命名标签,除非它存在,在这种情况下我会更新标签上的 tag_id 但我担心它会与 taggings_count 或其他东西混淆。

    免责声明:我们在几年前就摆脱了acts_as_taggable_on,所以我有一段时间没有机会使用它,也没有测试过以下解决方案。

    话虽如此,你提到的似乎是要走的路。

    def new_format(name)
      "new_#{name}"
    end
    
    tags = %i(tags you want to rename)
    model = 'MyModel'
    context = :context
    
    ActsAsTaggable::Tag.joins(:taggings).where(name: tags).find_each do |tag|
      if tag.taggings.count == 1
        # this tag is only used in the context we're updating,
        # so we can rename in place
        tag.update(name: new_format(tag.name))
      else
        # this tag is used elsewhere, so we need to create a new tag,
        # update the taggings we care about, and fix the `taggings_count`s
        new_tag = ActsAsTaggable::Tag.create!(name: new_format(tag.name))
        updated = ActsAsTaggable::Tagging.where(
          tag: tag, 
          taggable_type: model, 
          context: context).update_all(tag: new_tag)
        ActsAsTaggableOn::Tag.update_counters(tag.id, taggings_count: -updated)
        ActsAsTaggableOn::Tag.update_counters(new_tag.id, taggings_count: updated)
      end
    end
    

    ActiveRecord::Relation.update_all 直接进入 SQL,不触及相关记录。 ActiveRecord::CounterCache.update_counters 默认也不接触记录。

    【讨论】:

      猜你喜欢
      • 2015-09-17
      • 2021-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-20
      • 1970-01-01
      • 2018-07-31
      相关资源
      最近更新 更多