class CreatePostVersions < ActiveRecord::Migration[8.0] def change create_table :post_versions do |t| t.references :post, null: false, foreign_key: true t.integer :version_no, null: false t.string :event_type, null: false t.string :title t.string :url, limit: 768, null: false t.string :thumbnail_base, limit: 2000 t.text :tags, null: false t.references :parent, foreign_key: { to_table: :posts } t.datetime :original_created_from t.datetime :original_created_before t.datetime :created_at, null: false t.references :created_by_user, foreign_key: { to_table: :users } t.index [:post_id, :version_no], unique: true t.check_constraint 'version_no > 0' t.check_constraint "event_type IN ('create', 'update', 'discard', 'restore')" end reversible do |dir| dir.up do execute <<~SQL INSERT INTO post_versions( post_id , version_no , event_type , title , url , thumbnail_base , tags , parent_id , original_created_from , original_created_before , created_at , created_by_user_id) SELECT posts.id , 1 , 'create' , posts.title , posts.url , posts.thumbnail_base , COALESCE(tag_snapshots.tags, '') , posts.parent_id , posts.original_created_from , posts.original_created_before , posts.created_at , posts.uploaded_user_id FROM posts LEFT JOIN ( SELECT post_tags.post_id , GROUP_CONCAT(tag_names.name ORDER BY tag_names.name SEPARATOR ' ') AS tags FROM post_tags INNER JOIN tags ON tags.id = post_tags.tag_id INNER JOIN tag_names ON tag_names.id = tags.tag_name_id WHERE post_tags.discarded_at IS NULL GROUP BY post_tags.post_id ) tag_snapshots ON tag_snapshots.post_id = posts.id SQL end end end end