mbleigh / acts-as-taggable-on

A tagging plugin for Rails applications that allows for custom tagging along dynamic contexts.
http://mbleigh.lighthouseapp.com/projects/10116-acts-as-taggable-on
MIT License
4.95k stars 1.18k forks source link

Install / migration error on Rails 7.0.2.2 #1078

Open atomical opened 2 years ago

atomical commented 2 years ago

ActiveRecord::MismatchedForeignKey: Column `tag_id` on table `taggings` does not match column `id` on `tags`, which has type `bigint(20)`. To resolve this issue, change the type of the `tag_id` column on `taggings` to be :bigint. (For example `t.bigint :tag_id`).```
dieter-medium commented 2 years ago

looks like a regression within rails, I was able to workaround via:

# 20220319093244_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb
# t.references :tag, foreign_key: { to_table: ActsAsTaggableOn.tags_table }
t.references :tag, foreign_key: { to_table: ActsAsTaggableOn.tags_table }, type: :bigint

&&

# 20220319093245_add_missing_unique_indices.acts_as_taggable_on_engine.rb

# Mysql2::Error: Cannot drop index 'index_taggings_on_tag_id': needed in a foreign key constraint
# remove_index ActsAsTaggableOn.taggings_table, :tag_id if index_exists?(ActsAsTaggableOn.taggings_table, :tag_id)
jmlagace commented 2 years ago

I can confirm the problem is also applicable to Rails 6.1.5.

@dieter-medium's workaround works as on that version too.

pattyr commented 2 years ago

We've been having this issue and noticed a couple things, maybe someone can clarify what happened?

Looking at commits starting Jan 6, it looks like a fix was merged, but then in the commit after (release 9.0.1 - which looks like it specifically for this issue) got partially reverted?

Was that an intentional revert (and why) or a maybe bad merge? TYIA for any insight. 😃

davidlbean commented 1 year ago

I fixed my migration issue with the dropping of foreign key indexes by adding a function to be more careful about how it gets done...probably necessary b/c I'm on mysql. No guarantees this is the best way...just fixing it fast for myself but adding here in case it helps someone else:


# This migration comes from acts_as_taggable_on_engine (originally 2)
class AddMissingUniqueIndices < ActiveRecord::Migration[6.0]
  def self.up
    tags_table = ActsAsTaggableOn.tags_table
    taggings_table = ActsAsTaggableOn.taggings_table

    add_index tags_table, :name, unique: true

    safely_remove_index(table_name: taggings_table, column_name: :tag)
    safely_remove_index(table_name: taggings_table, index_name: 'taggings_taggable_context_idx')

    add_index taggings_table,
              %i[tag_id taggable_id taggable_type context tagger_id tagger_type],
              unique: true, name: 'taggings_idx'
  end

  def self.down
    remove_index ActsAsTaggableOn.tags_table, :name

    remove_index ActsAsTaggableOn.taggings_table, name: 'taggings_idx'

    add_index ActsAsTaggableOn.taggings_table, :tag_id unless index_exists?(ActsAsTaggableOn.taggings_table, :tag_id)
    add_index ActsAsTaggableOn.taggings_table, %i[taggable_id taggable_type context],
              name: 'taggings_taggable_context_idx'
  end

  def self.safely_remove_index(table_name:, column_name: nil, index_name: nil)
    raise ArgumentError, 'set either column_name or index_name' if column_name.nil? && index_name.nil?

    if column_name.present?
      # remove the foreign key if exists
      remove_foreign_key table_name, column: column_name if foreign_key_exists? table_name, column_name
      # refresh the table definition
      "ActsAsTaggableOn::#{table_name.to_s.singularize.camelize}".constantize.send :reset_column_information
      # now remove the index on that field if it exists
      remove_index table_name, column: column_name, if_exists: true if index_exists?(table_name, column_name)
    else
      "ActsAsTaggableOn::#{table_name.to_s.singularize.camelize}".constantize.send :reset_column_information
      remove_index table_name, name: index_name, if_exists: true if index_exists?(table_name, name: index_name)
    end
  end
end
barnaclebarnes commented 1 year ago

I fixed my migration issue with the dropping of foreign key indexes by adding a function to be more careful about how it gets done...probably necessary b/c I'm on mysql. No guarantees this is the best way...just fixing it fast for myself but adding here in case it helps someone else:

Just had to change line 39 to:

remove_index table_name, name: index_name, if_exists: true if index_name_exists?(table_name, index_name)