编写 aliyun-oss 存储实现的时候,顺便尝试了一把 ActiveStorage
与 Rails 结合很紧密,使用起来非常快捷简单,比 CarrierWave 好使很多!
增加了两个表:
active_storage_attachments
- 与业务表的多对多关系active_storage_blobs
- 附件的 Meta 信息,例如文件名,尺寸 ...假如我有个 photos
需要存储图片,大概是这样:
class Photo < ApplicationRecord
has_one_attached :image
end
这里,photos
表将不需要 image
字段,而是依靠 has_one
的关系来关联 active_storage_attachments
表。
这样带来了新的问题,每次列表查询,如果需要头像,需要关联查询。
于是问题来了,这样多余的开销怎么办?
可以依靠 Cache 来解决
class Photo < ApplicationRecord
has_one_attached :image
def image_url
# cache_key 带了 @photo 的 updated_at 信息,所以,每次 Photo 更新的时候,缓存能自动失效
Rails.cache.fetch(self.cache_key("image_url")) do
self.image.service_url
end
end
end
对,这样有好处,可以自由增加各种各样的附件类型,无需调整数据库。
class Post < ApplicationRecord
has_one_attached :image
has_one_attached :cover
has_many_attached :images
has_many_attached :attachments
end
direct_upload: true
的功能很方便,全交给客户端直接往云服务器上传,避免经过服务器,只需要这么一行:
<%= form.file_field :avatar, direct_upload: true %>