标签/标签组 CSV 导入区分大小写,但事实并非如此

复现:

  • 拥有一个名为 ABC 的标签
  • 创建一个带有标签 abc 的 CSV
  • 转到 /tags 并上传 CSV
  • 查看上传失败,显示“抱歉,上传 foo.csv 时出错。请重试。”

这是因为标签区分大小写,但它们必须在忽略大小写的情况下是唯一的。

如果您的文件包含 1000 个标签,那么找出问题所在将是一项艰巨的任务。

code 中的代码是这样做的:

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

这是一个糟糕的模式,因为 find_by_name 区分大小写而 create! 不区分大小写 [^1],因此会因 ActiveRecord::RecordInvalid : Validation failed: Name has already been taken 而出错。

这应该类似于:

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

[^1]:因为 validates :name, presence: true, uniqueness: { case_sensitive: false }

3 个赞

感谢你的报告,给这个加上一个 pr-welcome 标签吧,我猜我们需要将 find_by_name 改为不区分大小写的查找。

鉴于我们有:

修复方法如下:

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

TagGroup 缺少索引,所以我们需要添加它,然后在那里也做同样的事情。

@RGJ

我无法用普通标签重现您的问题但是在使用标签组时遇到了您提到的错误

这是我的示例 CSV:

ABC,TAGGROUP

ABC 可以正常工作,但使用 tag_group 会报错。如果您能分享一个示例 CSV,我很乐意提供帮助!

我已经提交了一个 PR 来修复标签组问题。另外,您的论坛是否启用了 SiteSetting.force_lowercase_tags

1 个赞

不,它未被选中。抱歉,我现在明白了,这很重要。

不确定您是如何尝试重现的,但 CSV 应该有一个小写的 abc 并且 force_lowercase_tags 应该未被选中。

1 个赞

没关系,这是我在代码中找到的一个站点设置,它可能很重要!

你的 CSV 只是 abc 而没有标签组?

我们的测试示例是(我在本地测试过,即使 capitaltag2 是大写,它也能正常工作):

我确实无法仅凭一个标签重现此问题。

我在我的原始帖子中犯了一个小错误:

Tag.find_by_name 不区分大小写(好),而 Tag.find_by(name: ) 区分大小写(不好)。
这是因为 David 7 年前通过覆盖 find_by_name 方法 为标签修复了此问题

对于 TagGroup,此修复从未应用过。

2 个赞