Active Storage의 핵심 구성 요소인 Blob과 Attachment는 다음과 같이 정의됩니다.
Blob (ActiveStorage::Blob)
Blob은 업로드된 파일에 대한 메타데이터를 저장하며, 실제 파일은 AWS S3, GCS, 디스크 등 스토리지 서비스에 저장됩니다. Blob은 해당 파일이 스토리지 서비스의 어디에 위치하는지에 대한 스토리지 키와 함께 다음 메타데이터를 보관합니다.
-
데이터베이스 테이블:
active_storage_blobs -
주요 컬럼:
key: 스토리지 서비스에서 바이트를 가져오는 데 사용되는 경로/키filename: 원본 파일명content_type: 파일의 MIME 타입byte_size: 파일 크기 (바이트 단위)checksum: 파일 무결성 검사metadata: JSON 형식 (이미지 크기, 분석 플래그 등)service_name: Blob이 저장된 스토리지 서비스 이름Timestamps
Blob은 특정하고 변경 불가능한 파일을 나타내도록 설계되었습니다. 한 번 생성된 Blob은 항상 동일한 파일 데이터를 가리켜야 합니다. 파일 내용을 변경해야 할 경우(예: 이미지 크기 조정, 워터마크 추가), 새로운 파일에 대해 완전히 새로운 Blob을 생성하고, 이전 Blob이 더 이상 필요하지 않다면 제거(purge)하는 것이 올바른 접근 방식입니다. 이러한 불변성은 애플리케이션 전반에서 Blob을 예측 가능하고 안전하게 참조할 수 있도록 합니다.
Attachment (ActiveStorage::Attachment)
Attachment는 Blob을 애플리케이션 모델에 연결하는 다형성 조인 테이블입니다. Attachment는 레코드와 Blob에 속하지만, Blob은 레코드에 직접 속하지 않습니다. 레코드에서 Blob을 가져오려면 Attachment를 거쳐야 합니다. Attachment는 하나의 모델 레코드와 명명된 슬롯(예: “avatar”, “documents”)을 하나의 Blob에 연결하는 역할을 합니다.
-
데이터베이스 테이블:
active_storage_attachments -
주요 컬럼:
name: 모델의 연결 이름 (:avatar,:files등)record_type/record_id: 연결된 모델/행blob_id: 가리키는 Blob의 IDTimestamp
작동 방식:
User 모델의 has_one_attached :avatar 또는 Project 모델의 has_many_attached :documents와 같은 선언은 Attachment 연결을 정의합니다. user.avatar.attach(...)를 실행하면 Active Storage는 다음 세 가지 작업을 수행합니다.
-
업로드된 파일을 나타내는 Blob을 생성하고 메타데이터를 저장합니다.
-
파일을 스토리지 서비스에 업로드합니다.
-
user모델 레코드를 해당 Blob에 연결하는 Attachment를 생성합니다.
하나의 Blob은 여러 번(동일하거나 다른 모델에) 연결될 수 있으며, 이는 파일을 다시 업로드할 필요 없이 재사용하는 방법입니다. 각 사용은 동일한 Blob과 다른 레코드를 가리키는 별도의 Attachment 행을 생성합니다.
파일 교체 및 삭제:
-
detach: 레코드와 Blob 간의 연결(Attachment)만 삭제하고 싶을 때 사용합니다(예:user.avatar.detach). 이는 Attachment 행을 파괴하지만, 실제 파일은 그대로 유지됩니다. 다른 레코드가 해당 Blob을 여전히 사용하고 있다면 Blob은 그대로 남아있습니다. -
purge: Attachment와 Blob 모두를 삭제하고 싶을 때 사용합니다(예:user.avatar.purge). 이는 스토리지 서비스에서 실제 파일을 제거합니다. 네트워크 호출이 발생하므로, 백그라운드 작업으로 수행하려면purge_later메서드를 사용합니다.
Blob으로 할 수 있는 작업
Blob은 파일 메타데이터 읽기, 바이트 다운로드, URL 생성, 콘텐츠 분석, 수동 Blob 생성 등 파일 작업을 위한 풍부한 API를 제공합니다.
-
서명된 URL 생성:
rails_blob_url(blob)또는<%= image_tag url_for(user.avatar) %>를 통해 안전하고 만료되는 URL을 생성합니다. -
메타데이터 접근:
blob.filename,blob.content_type,blob.byte_size,blob.checksum,blob.metadata,blob.service_name등을 통해 파일 정보를 얻습니다. -
실제 파일 데이터 읽기/다운로드:
blob.download(전체 파일),blob.open(Tempfile),blob.download { |chunk| ... }(스트리밍)을 통해 파일 바이트에 접근합니다. -
파일 분석:
blob.analyze를 통해 이미지 크기, 비디오 길이 등 특정 파일 형식의 메타데이터를 자동으로 추출합니다. -
Blob 수동 생성:
ActiveStorage::Blob.create_and_upload!또는ActiveStorage::Blob.create_after_upload!를 사용하여 스크립트나 백그라운드 작업에서 직접 Blob을 생성할 수 있습니다.