记录一次网站的升级 tag 库的升级改造

网站的多个模块依赖于 tag 功能,而且与多个表之间的对应关系是多对多,原来的建表方式有点问题
更新于: 2022-04-11 02:42:31

背景

原来网站的功能与 tag 有依赖,是采用一个功能,一个中间表的方式进行的

现在功能模块增多,而且多用 tag 来进行关联,用以上方式显然有些不合理

引入自己写的模块: rails_taggable 来解决这个问题

引入包,以及配置

# 添加到 Gemfile
gem 'rails_taggable'

# add migrations to app/db/migrations directory
rails g rails_taggable:install

# add config/initializers/rails_taggable.rb
rails g rails_taggable:initializer

添加自己的配置

~rails/config/initializers/rails_taggable.rb

RailsTaggable.setup do |config|
  config.models = ['Post', 'Snippet', 'Work']
end

改造 models

# post.rb
# work.rb
# snippet.rb

# 添加这个
include RailsTaggable::Taggable

# 去掉
# has_and_belongs_to_many :tags

改造 controler/concerts/taggale 模块

module Taggable
  def update_tags(model)
    model.tags.destroy_all
    model.tags = params[:tags].map do |name|
      RailsTaggable::Tag.find_or_create_by(name: name)
    end
  end
end

导出原tags表里数据

  • 导出 tags 数据 
  • 导入到新的 rails_taggable_tags

迁移关联表数据

  • PostsTag
  • SnippetsTag
  • TagsWork
# PostsTag
records = PostsTag.all
records.each do |record|
  RailsTaggable::Tagging.create(
    taggable_id: record.post_id,
    tag_id: record.tag_id,
    taggable_type: :Post
  )
end
# SnippetsTag
records = SnippetsTag.all
records.each do |record|
  RailsTaggable::Tagging.create(
    taggable_id: record.snippet_id,
    tag_id: record.tag_id,
    taggable_type: :Snippet
  )
end
# TagsWork
records = TagsWork.all
records.each do |record|
  RailsTaggable::Tagging.create(
    taggable_id: record.work_id,
    tag_id: record.tag_id,
    taggable_type: :Work
  )
end

清理 migrations

  • 20211012053346_create_posts_tags
  • 20211026014432_create_snippets_tags
  • 20211216061120_create_tags_works

清理无用的表

  • snippets_tags
  • posts_tags
  • tags_works
  • tags