운영 중인 공개 사이트에서 이모지가 깨지는 현상을 발견했습니다. 해당 사이트의 ACL은 private로 설정되어 있으며, access control post dictates security | source: post creator라는 이유로 secure로 표시되어 있습니다.
uploads:secure_upload_analyse_and_update 태스크를 실행하면 문제가 해결되지만, 며칠 후 다시 발생합니다. 사이트 로고에서도 한 번 같은 문제가 발생했으나, 그 이후로는 다시 일어나지 않았습니다.
안녕하세요 @Wolftallemo, 커스텀 이모지(또는 게시글에서 사용될 수 있는 공개적으로 접근 가능한 업로드)과 보안 업로드가 함께 사용될 때 꽤 까다로운 문제입니다. 얼마 전부터 어떤 업로드가 무엇에 연결되어 있는지 확인하기 위해 UploadReference 테이블을 사용하기 시작했는데, 이 테이블로 마이그레이션할 때 모든 created_at 날짜시간 값을 동일한 값으로 설정했습니다. 그 결과, 보안 목적으로 업로드의 최초 사용이 공개적인 것인지 확인하는 과정에서 정렬이 어긋나고 잘못된 값을 사용하는 경우가 발생했습니다. 두 값의 created_at이 정확히 동일하다면 PostgreSQL은 자체적으로 처리하기 때문입니다:
질문자님의 언급 덕분에 이 문제를 다시 살펴봤고, created_at ASC 기준으로 정렬한 이후id ASC 기준으로 정렬하면 이러한 충돌이 발생할 경우 실제 첫 번째 레코드가 사용되도록 더 잘 처리할 수 있다고 생각합니다.
이 PR이 병합된 후(오늘 병합될 수 있도록 노력하겠습니다) 문제가 지속되고, 질문자님이 사이트를 업로드하셨다면 추가적인 옵션에 대해 논의할 수 있습니다. 하지만 이것이 질문자님의 문제의 원인일 것이라 의심하고 있습니다. 질문자님의 사이트에서 다음을 실행하고 결과를 비교하여 확인할 수 있습니다:
CustomEmoji.find_by(name: "success").upload.upload_references.order("created_at ASC")
CustomEmoji.find_by(name: "success").upload.upload_references.order("created_at ASC, id ASC")
첫 번째 쿼리의 경우 target_type이 Post여야 하고, 두 번째 쿼리의 경우 target_type이 CustomEmoji여야 합니다.
흥미롭네요, 그러면 올바른 값을 반환하고 있는 것이군요. 링크된 업로드에 대해 security_last_changed_reason과 security_last_changed_at 값을 게시해 주시고, access_control_post_id가 채워져 있는지 확인해 주시겠습니까? 첫 번째 참조가 커스텀 이모지인 경우 해당 업로드를 보안 상태로 표시해서는 안 됩니다. 이것도 시도해 보세요:
Upload.find(ID)
.upload_references
.joins(<<~SQL)
LEFT JOIN posts ON upload_references.target_type = 'Post' AND upload_references.target_id = posts.id
SQL
.where("posts.deleted_at IS NULL")
.order("upload_references.created_at ASC, upload_references.id ASC")
.first