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

재현 방법:

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

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

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

코드는 다음과 같이 동작합니다

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 } 때문 ↩︎

4개의 좋아요

리포트해 주셔서 감사합니다. 이 이슈에 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를 전부 대문자로 설정하여 로컬에서 테스트해 보았지만, 예상대로 잘 작동했습니다):

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

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

Tag.find_by_name는 대소문자를 구분하지 않습니다(좋습니다). 반면 Tag.find_by(name: )는 대소문자를 구분합니다(나쁩니다).
이것은 David가 7년 전 find_by_name 메서드를 오버라이드하여 태그에 대해 이미 수정했기 때문입니다.

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

2개의 좋아요