rails-active-storage
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRails Active Storage
Rails Active Storage
Active Storage provides a framework for attaching files to Active Record models through cloud storage services like Amazon S3, Google Cloud Storage, or local disk storage. It handles file uploads, transformations, previews, and lifecycle management with minimal configuration.
Active Storage 提供了一个框架,可通过Amazon S3、Google Cloud Storage或本地磁盘存储等云存储服务将文件附加到Active Record模型。它只需极少配置即可处理文件上传、转换、预览和生命周期管理。
When to Use Active Storage
何时使用Active Storage
- File attachments: Attach avatars, documents, media files to models
- Cloud storage integration: Configure S3, Google Cloud Storage, or other services
- Image processing: Generate thumbnails, resize images, create variants
- File analysis: Extract metadata from images, videos, and PDFs
- Direct uploads: Allow users to upload directly to cloud storage
- File serving: Redirect or proxy files with signed URLs
- Multi-service support: Mirror files across multiple storage backends
- Testing: Use disk storage for development and testing
- 文件附件:将头像、文档、媒体文件附加到模型
- 云存储集成:配置S3、Google Cloud Storage或其他服务
- 图片处理:生成缩略图、调整图片大小、创建变体
- 文件分析:从图片、视频和PDF中提取元数据
- 直接上传:允许用户直接上传到云存储
- 文件分发:通过签名URL重定向或代理文件
- 多服务支持:在多个存储后端之间镜像文件
- 测试:在开发和测试中使用磁盘存储
Quick Start
快速开始
1. Installation & Setup
1. 安装与设置
bash
undefinedbash
undefinedGenerate migrations and set up storage tables
生成迁移并设置存储表
rails active_storage:install
rails db:migrate
Configure storage services in `config/storage.yml`:
```yaml
local:
service: Disk
root: <%= Rails.root.join("storage") %>
amazon:
service: S3
access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
region: us-east-1
bucket: my-app-<%= Rails.env %>
google:
service: GCS
credentials: <%= Rails.root.join("path/to/keyfile.json") %>
project: my-project
bucket: my-app-<%= Rails.env %>Set the default service in :
config/environments/development.rbruby
config.active_storage.service = :localrails active_storage:install
rails db:migrate
在`config/storage.yml`中配置存储服务:
```yaml
local:
service: Disk
root: <%= Rails.root.join("storage") %>
amazon:
service: S3
access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
region: us-east-1
bucket: my-app-<%= Rails.env %>
google:
service: GCS
credentials: <%= Rails.root.join("path/to/keyfile.json") %>
project: my-project
bucket: my-app-<%= Rails.env %>在中设置默认服务:
config/environments/development.rbruby
config.active_storage.service = :local2. Attach Files to Models
2. 为模型附加文件
Single File Attachment (has_one_attached)
单个文件附件(has_one_attached)
ruby
class User < ApplicationRecord
has_one_attached :avatar
endUse in forms:
erb
<%= form.file_field :avatar, direct_upload: true %>Handle in controller:
ruby
class UsersController < ApplicationController
def create
@user = User.create!(user_params)
redirect_to @user
end
private
def user_params
params.expect(user: [:name, :email, :avatar])
end
endAttach to existing records:
ruby
user.avatar.attach(params[:avatar])
user.avatar.attached? # => trueruby
class User < ApplicationRecord
has_one_attached :avatar
end在表单中使用:
erb
<%= form.file_field :avatar, direct_upload: true %>在控制器中处理:
ruby
class UsersController < ApplicationController
def create
@user = User.create!(user_params)
redirect_to @user
end
private
def user_params
params.expect(user: [:name, :email, :avatar])
end
end附加到现有记录:
ruby
user.avatar.attach(params[:avatar])
user.avatar.attached? # => trueMultiple File Attachments (has_many_attached)
多个文件附件(has_many_attached)
ruby
class Message < ApplicationRecord
has_many_attached :images
endAttach multiple files:
ruby
@message.images.attach(params[:images])
@message.images.attached? # => trueruby
class Message < ApplicationRecord
has_many_attached :images
end附加多个文件:
ruby
@message.images.attach(params[:images])
@message.images.attached? # => true3. Serve Files
3. 分发文件
Generate permanent URLs:
ruby
url_for(user.avatar)生成永久URL:
ruby
url_for(user.avatar)rails_blob_path(user.avatar, disposition: "attachment")
rails_blob_path(user.avatar, disposition: "attachment")
=> Download link
=> 下载链接
Display in views:
```erb
<%= image_tag user.avatar %>
<%= link_to "Download", rails_blob_path(user.avatar, disposition: "attachment") %>
在视图中显示:
```erb
<%= image_tag user.avatar %>
<%= link_to "下载", rails_blob_path(user.avatar, disposition: "attachment") %>4. Transform Images
4. 转换图片
Create variants with on-demand transformation:
ruby
class User < ApplicationRecord
has_one_attached :avatar do |attachable|
attachable.variant :thumb, resize_to_limit: [100, 100]
end
endUse variants in views:
erb
<%= image_tag user.avatar.variant(:thumb) %>创建按需转换的变体:
ruby
class User < ApplicationRecord
has_one_attached :avatar do |attachable|
attachable.variant :thumb, resize_to_limit: [100, 100]
end
end在视图中使用变体:
erb
<%= image_tag user.avatar.variant(:thumb) %>5. Remove Files
5. 删除文件
Synchronously delete files:
ruby
user.avatar.purge # Synchronous
user.avatar.purge_later # Async via Active Job同步删除文件:
ruby
user.avatar.purge # 同步
user.avatar.purge_later # 通过Active Job异步Core Topics
核心主题
Setup & Configuration: See setup-and-configuration.md for disk and cloud service setup, environment configuration, and credentials management.
Attaching Files: See attaching-files.md for , , attaching file/IO objects, form handling, and validation strategies.
has_one_attachedhas_many_attachedFile Operations: See file-operations.md for querying attachments, removing files, downloading file contents, analyzing files, and handling blob metadata.
Serving & Transformations: See serving-and-transformations.md for URL generation, redirect vs proxy modes, image variants, previews, and CDN integration.
Direct Uploads: See direct-uploads.md for client-side uploads, CORS configuration, JavaScript events, and integrating with upload libraries.
Testing: See testing.md for test configuration, file fixtures, cleaning up test files, and mocking storage services.
Advanced Patterns: See references/REFERENCE.md for production deployments, multiple databases, mirror services, implementing custom services, and real-world examples.
设置与配置:查看setup-and-configuration.md了解磁盘和云服务设置、环境配置以及凭据管理。
附加文件:查看attaching-files.md了解、、附加文件/IO对象、表单处理和验证策略。
has_one_attachedhas_many_attached文件操作:查看file-operations.md了解查询附件、删除文件、下载文件内容、分析文件以及处理Blob元数据。
分发与转换:查看serving-and-transformations.md了解URL生成、重定向与代理模式、图片变体、预览以及CDN集成。
直接上传:查看direct-uploads.md了解客户端上传、CORS配置、JavaScript事件以及与上传库的集成。
测试:查看testing.md了解测试配置、文件夹具、清理测试文件以及模拟存储服务。
高级模式:查看references/REFERENCE.md了解生产部署、多数据库、镜像服务、实现自定义服务以及实际案例。
Examples
示例
See examples.md for practical implementations including:
- User profile with avatar and gallery
- Document management with file analysis
- Media library with transformations
- Direct upload with progress tracking
- Custom authenticated file serving
查看examples.md获取实用实现,包括:
- 带头像和图库的用户资料
- 带文件分析的文档管理
- 带转换的媒体库
- 带进度跟踪的直接上传
- 自定义认证的文件分发
Key Concepts
核心概念
Blobs
Blobs
Blobs represent files stored in your service. Each blob has:
- — the original file name
filename - — MIME type (image/png, application/pdf, etc.)
content_type - — file size in bytes
byte_size - — content hash for integrity verification
checksum - — custom key-value data
metadata
Blobs代表存储在服务中的文件。每个Blob包含:
- — 原始文件名
filename - — MIME类型(image/png、application/pdf等)
content_type - — 文件大小(字节)
byte_size - — 用于完整性验证的内容哈希
checksum - — 自定义键值数据
metadata
Attachments
Attachments
Attachments are polymorphic join records connecting models to blobs:
- Enable one-to-one relationships with
has_one_attached - Enable one-to-many relationships with
has_many_attached - Automatically handle file lifecycle with dependent destroy
Attachments是连接模型与Blobs的多态关联记录:
- 使用实现一对一关系
has_one_attached - 使用实现一对多关系
has_many_attached - 自动处理文件的生命周期(依赖销毁)
Variants
Variants
Variants are processed representations of blobs:
- Transform images on-demand (resize, crop, format conversion)
- Lazy-loaded by default for performance
- Supports ImageMagick and libvips processors
- Can be pre-generated for frequently-accessed images
Variants是Blob的处理后表示:
- 按需转换图片(调整大小、裁剪、格式转换)
- 默认延迟加载以提升性能
- 支持ImageMagick和libvips处理器
- 可为频繁访问的图片预生成
Direct Uploads
Direct Uploads
Direct uploads bypass your application servers:
- Files upload directly to cloud storage
- Reduces server load and bandwidth
- Retains uploads when form validation fails
- Requires CORS configuration on cloud storage
直接上传绕过应用服务器:
- 文件直接上传到云存储
- 降低服务器负载和带宽消耗
- 表单验证失败时保留上传内容
- 需要在云存储上配置CORS
Common Patterns
常见模式
Avatar Management
头像管理
ruby
class User < ApplicationRecord
has_one_attached :avatar do |attachable|
attachable.variant :medium, resize_to_limit: [400, 400]
attachable.variant :thumb, resize_to_limit: [150, 150]
end
validate :avatar_content_type
private
def avatar_content_type
return unless avatar.attached?
unless avatar.content_type.in?(%w[image/jpeg image/png image/gif])
errors.add(:avatar, "must be a valid image")
end
end
endruby
class User < ApplicationRecord
has_one_attached :avatar do |attachable|
attachable.variant :medium, resize_to_limit: [400, 400]
attachable.variant :thumb, resize_to_limit: [150, 150]
end
validate :avatar_content_type
private
def avatar_content_type
return unless avatar.attached?
unless avatar.content_type.in?(%w[image/jpeg image/png image/gif])
errors.add(:avatar, "必须是有效的图片")
end
end
endDocument Upload with Analysis
带分析的文档上传
ruby
class Document < ApplicationRecord
has_one_attached :file
after_create_commit :analyze_document
private
def analyze_document
return unless file.attached?
puts "File: #{file.filename}"
puts "Size: #{file.byte_size} bytes"
puts "Type: #{file.content_type}"
puts "Analyzed: #{file.analyzed?}"
# Use metadata from file.metadata for further processing
end
endruby
class Document < ApplicationRecord
has_one_attached :file
after_create_commit :analyze_document
private
def analyze_document
return unless file.attached?
puts "File: #{file.filename}"
puts "Size: #{file.byte_size} bytes"
puts "Type: #{file.content_type}"
puts "Analyzed: #{file.analyzed?}"
# 使用file.metadata中的元数据进行进一步处理
end
endImage Gallery
图片图库
ruby
class Post < ApplicationRecord
has_many_attached :images do |attachable|
attachable.variant :display, resize_to_limit: [800, 600]
attachable.variant :thumb, resize_to_limit: [200, 200]
end
endruby
class Post < ApplicationRecord
has_many_attached :images do |attachable|
attachable.variant :display, resize_to_limit: [800, 600]
attachable.variant :thumb, resize_to_limit: [200, 200]
end
endIn view:
在视图中:
<%= @post.images.each do |image| %>
<%= image_tag image.variant(:display) %>
<% end %>
undefined<%= @post.images.each do |image| %>
<%= image_tag image.variant(:display) %>
<% end %>
undefinedQuerying Attachments
查询附件
ruby
undefinedruby
undefinedFind users with avatars
查找带有头像的用户
User.joins(:avatar_attachment).distinct
User.joins(:avatar_attachment).distinct
Find messages with only video attachments
查找仅带有视频附件的消息
Message.joins(:images_blobs).where(active_storage_blobs: { content_type: "video/mp4" })
Message.joins(:images_blobs).where(active_storage_blobs: { content_type: "video/mp4" })
Eager load to prevent N+1
预加载以避免N+1查询
Post.includes(:images_attachments, :images_blobs)
undefinedPost.includes(:images_attachments, :images_blobs)
undefinedImportant Notes
重要说明
- Requirements: Image processing requires libvips or ImageMagick; video/PDF processing needs ffmpeg and poppler
- Credentials: Use Rails credentials () to manage AWS/GCS keys
rails credentials:edit - Storage Isolation: Use Rails.env in bucket names to prevent accidental data loss
- Direct Upload Safety: Validate file types and sizes on both client and server
- Testing: Configure to use disk service instead of cloud storage
config/storage/test.yml - N+1 Queries: Use eager loading with when displaying multiple attachments
includes(:*_attachments, :*_blobs)
- 要求:图片处理需要libvips或ImageMagick;视频/PDF处理需要ffmpeg和poppler
- 凭据:使用Rails凭据()管理AWS/GCS密钥
rails credentials:edit - 存储隔离:在存储桶名称中使用Rails.env以防止意外数据丢失
- 直接上传安全:在客户端和服务器端都验证文件类型和大小
- 测试:配置以使用磁盘服务而非云存储
config/storage/test.yml - N+1查询:显示多个附件时,使用进行预加载
includes(:*_attachments, :*_blobs)