# 태그/태그 그룹 CSV 가져오기는 대소문자를 구별해야 하지만 실제로는 구별하지 않음

**URL:** https://meta.discourse.org/t/tag-taggroup-csv-import-is-case-aware-but-its-not/381450
**Category:** Bug
**Tags:** pr-welcome
**Created:** [9월 3, 2025, 4:19오후 UTC](https://meta.discourse.org/t/tag-taggroup-csv-import-is-case-aware-but-its-not/381450 "2025-09-03T16:19:17Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [9월 3, 2025, 4:19오후 UTC](https://meta.discourse.org/t/tag-taggroup-csv-import-is-case-aware-but-its-not/381450/1 "2025-09-03T16:19:17Z")

</div>

재현 방법:

- ABC라는 이름의 태그가 있는 경우
- abc 태그를 포함하는 CSV 파일을 생성합니다.
- /tags 페이지로 이동하여 CSV 파일을 업로드합니다.
- “Sorry, there was an error uploading foo.csv. Please try again.” 오류 메시지와 함께 실패하는 것을 확인합니다.

이 문제는 태그가 대소문자를 구별하지만, 고유성은 대소문자를 무시해야 하기 때문에 발생합니다.

1000개의 태그가 포함된 파일인 경우, 어디서 오류가 발생하는지 파악하는 것이 상당한 작업이 됩니다.

[코드](https://github.com/discourse/discourse/blob/main/app/controllers/tags_controller.rb#L250-L267)는 다음과 같이 동작합니다

```rb
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)

```

이것은 `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 }` 때문

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [9월 15, 2025, 2:04오전 UTC](https://meta.discourse.org/t/tag-taggroup-csv-import-is-case-aware-but-its-not/381450/2 "2025-09-15T02:04:12Z")

</div>

리포트해 주셔서 감사합니다. 이 이슈에 #pr-welcome 태그를 달아두겠습니다. find\_by\_name을 대소문자를 구분하지 않는 검색으로 변경해야 할 것 같습니다.

현재 다음과 같은 코드가 있습니다:

> <https://github.com/discourse/discourse/blob/4474f131951aad0b3aaa11708aad233bc8b4ba99/app/models/tag.rb#L292-L292>

수정 방법은 다음과 같습니다:

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

```

TagGroup에는 인덱스가 빠져 있으므로, 인덱스를 추가한 후 동일한 방식으로 수정해야 합니다.

---

<div class="post-metadata">

### Author: ![gabriel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gabriel/32/367911_2.png) [@gabriel](https://meta.discourse.org/u/gabriel)
#### Post date: [11월 5, 2025, 4:42오후 UTC](https://meta.discourse.org/t/tag-taggroup-csv-import-is-case-aware-but-its-not/381450/4 "2025-11-05T16:42:37Z")

</div>

안녕하세요 @RGJ

일반 태그로는 해당 문제를 재현할 수 없었지만, 태그 그룹에서는 말씀하신 오류가 발생했습니다.

제 샘플 CSV는 다음과 같습니다:

```csv
ABC,TAGGROUP

```

ABC는 정상적으로 작동하지만, tag\_group을 사용하면 오류가 발생합니다. 샘플 CSV를 공유해 주시면 기꺼이 도움을 드리겠습니다!

태그 그룹 문제를 수정하는 [PR](https://github.com/discourse/discourse/pull/35837)을 만들었습니다. 또한, 포럼에서 `SiteSetting.force_lowercase_tags`가 활성화되어 있나요?

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [11월 5, 2025, 6:00오후 UTC](https://meta.discourse.org/t/tag-taggroup-csv-import-is-case-aware-but-its-not/381450/5 "2025-11-05T18:00:16Z")

</div>

> [@gabriel](#):
>
> 포럼에서 `SiteSetting.force_lowercase_tags`가 활성화되어 있나요?

아니요, 체크가 해제되어 있습니다. 죄송합니다, 이제 그것이 중요하다는 것을 알겠습니다.

> [@RGJ](#):
>
> ABC라는 이름의 태그를 가지고  
> abc 태그가 포함된 CSV를 생성합니다

> [@gabriel](#):
>
> 제 샘플 CSV는 다음과 같습니다:
> 
> `ABC,TAGGROUP`

어떻게 재현하려는 것인지 확실하지 않지만, CSV에는 소문자 `abc`가 포함되어야 하고 `force_lowercase_tags`는 체크 해제 상태여야 합니다.

---

<div class="post-metadata">

### Author: ![gabriel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gabriel/32/367911_2.png) [@gabriel](https://meta.discourse.org/u/gabriel)
#### Post date: [11월 5, 2025, 6:10오후 UTC](https://meta.discourse.org/t/tag-taggroup-csv-import-is-case-aware-but-its-not/381450/6 "2025-11-05T18:10:43Z")

</div>

> [@RGJ](#):
>
> 아니요, 체크되지 않았습니다. 죄송합니다. 이제 그게 중요하다는 걸 알겠습니다.

걱정 마세요. 제가 코드를 파헤치다 발견한 사이트 설정이었는데, 중요할 수 있거든요!

> [@RGJ](#):
>
> 하지만 CSV에는 소문자 `abc`가 있어야 합니다.

그 CSV는 태그 그룹이 없는 `abc`만 있는 건가요?

우리의 테스트 예시는 다음과 같습니다(대문자 `capitaltag2`를 전부 대문자로 설정하여 로컬에서 테스트해 보았지만, 예상대로 잘 작동했습니다):

> <https://github.com/discourse/discourse/blob/7ac08f936e24572842bd93c122a794dd9c0ec3d5/spec/fixtures/csv/tags.csv>

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [11월 7, 2025, 12:04오후 UTC](https://meta.discourse.org/t/tag-taggroup-csv-import-is-case-aware-but-its-not/381450/7 "2025-11-07T12:04:09Z")

</div>

실제로 태그만으로는 재현할 수 없습니다.

OP에서 작은 실수를 했습니다:

`Tag.find_by_name`는 대소문자를 구분하지 않습니다(좋습니다). 반면 `Tag.find_by(name: )`는 대소문자를 구분합니다(나쁩니다).  
이것은 David가 7년 전 `find_by_name` 메서드를 오버라이드하여 [태그에 대해 이미 수정했기 때문](https://github.com/discourse/discourse/blame/main/app/models/tag.rb#L134-L137)입니다.

`TagGroup`의 경우 이 수정이 적용된 적이 없습니다.
