Tag / TagGroup CSV import is case aware, but it's not

Reproduction:

  • Have a tag called ABC
  • Create a CSV with tag abc
  • Go to /tags and upload CSV
  • See it fail with “Sorry, there was an error uploading foo.csv. Please try again.”

This is happening because tags are case aware but they must be unique ignoring the case.

If you have a file with 1000 tags it is quite a job to figure out where it goes wrong.

The code does this

tag = Tag.find_by_name(tag_name) || Tag.create!(name: tag_name)
...
tag_group = TagGroup.find_by(name: tag_group_name) || TagGroup.create!(name: tag_group_name)

which is a bad pattern, since find_by_name is case sensitive and create! is not [1] so it errors out with ActiveRecord::RecordInvalid : Validation failed: Name has already been taken

This should be something like

tag = Tag.where('name ILIKE ?', tag_name).first || Tag.create!(name: tag_name)


  1. because validates :name, presence: true, uniqueness: { case_sensitive: false } ↩︎

3 Likes

Thanks for reporting, put a pr-welcome on this, I guess we need to change that find_by_name to do a case insensitive lookup.

Given we have:

The fix would be:

tag = Tag.where('lower(name) = ?', tag_name.downcase).first

TagGroup is missing the index, so we would need to add it and then do the same there.