Rails 关于 ActiveStorage 的几个问题

jonnoj · 2018年06月08日 · 最后由 jonnoj 回复于 2018年06月09日 · 2927 次阅读

请问怎么自定义文件名?(已解决)

比如我上传了中文名的文件,是直接上传到 amazon s3 的,有没有办法在上传前将文件名重命名?

怎样在展示上传图片时修改 url 指定自定义路径?(已解决)

我用 amazon lambda 做图片缩略图处理后,将文件存到 bucket 里的指定目录里,想在展示时自定义 url,比如给文件名加入后缀来展示图片。 ActiveStorage 只看到用 url_for 的方式,有没有办法自定义?

N+1 问题怎么解决?(未解决)

比如我的一个Post Model 有两张图片,我设置 has_many_attached :images

当我在 controller 里Post.find(1).images时,发现 console 会显示两条查询:

ActiveStorage::Blob Load (0.3ms)  SELECT  `active_storage_blobs`.* FROM `active_storage_blobs` WHERE `active_storage_blobs`.`id` = 23 LIMIT 1
 ActiveStorage::Blob Load (0.5ms)  SELECT  `active_storage_blobs`.* FROM `active_storage_blobs` WHERE `active_storage_blobs`.`id` = 24 LIMIT 1

请问怎么让他在一条里查询出来?

如何 counter_cache ActiveStorage 的个数?(未解决)


请问怎么自定义文件名?

ActiveStorage 的设计是上传的时候存储文件名在数据,下载(生成下载 URL)的时候指定 disposition 参数:

attachment.file.service_url(disposition: :attachment)

这样会告诉 S3 用之前数据库里面存储的文件名来实现 disposition 下载。

也就是能达到你要的得到原始文件名的效果。

怎样在展示上传图片时修改 url 指定自定义路径?

https://github.com/rails/rails/blob/master/activestorage/lib/active_storage/service/s3_service.rb#L67

Amazon S3 的实现貌似没有支持。

我做的 Aliyun 的就做过类似事情,实际上是在 service_url 生成的时候做了小动作。

https://github.com/huacnlee/activestorage-aliyun#use-for-image-url

N+1 问题怎么解决?

描述不清楚,查询的时候 includes 搞不了?

huacnlee 回复

请问关于问题 1: 请问怎么自定义文件名?

我想在上传前自定义文件名可以吗?比如把中文文件名重命名为以父Model的ID+时间戳的文件名,这样有办法实现吗?

关于问题 3

比如我的一个Post Model 有两张图片,我设置 has_many_attached :images

当我在 controller 里Post.find(1).images时,发现 console 会显示两条查询:

ActiveStorage::Blob Load (0.3ms)  SELECT  `active_storage_blobs`.* FROM `active_storage_blobs` WHERE `active_storage_blobs`.`id` = 23 LIMIT 1
 ActiveStorage::Blob Load (0.5ms)  SELECT  `active_storage_blobs`.* FROM `active_storage_blobs` WHERE `active_storage_blobs`.`id` = 24 LIMIT 1

请问怎么让他在一条里查询出来?

jonnoj 回复
post.image.service_url(filename: "post-#{post.id}-#{post.created_at}")
jonnoj 回复
Post.includes(:images).find(1).images
OrderSun 回复

显示错误:Association named 'images' was not found on Post; perhaps you misspelled it?

huacnlee 回复

谢谢回复,这个是上传后,下载的时候指定下载的文件名吧?我是想在上传前自定义文件名。

jonnoj 回复

..... 怎么这么死板,有何区别?结果都一样的

huacnlee 回复

因为我使用了 amazon lambda 做缩略图处理,要获取 S3 上面已处理的缩略图 url,用户自己上传的各种空格中文什么的,挺麻烦的。 😂

你理解有误,搜索 Context-Disposition 看看这是干嘛用的!

用户上传的时候完全可以生成一个随机的 URL,你不需要把文件名放 URL 里面

例如:

https://l.ruby-china.com/photo/2016/c309db0b49cab85a32f756541ea0e2b0.png

设定 disposition: :attachment, filename: "Foo Bar 中文.jpg",这个 URL 下载会得到 Foo Bar 中文.jpg

OrderSun 回复

images 是表名,单复数根据关联联系决定。

huacnlee 回复

试了一下,明白了,用 sdk 上传的确实是生成随机文件名在 bucket 里的,这样方便多了,多谢。

关于第三个 N+1 的问题的解决办法是Post.with_attached_images,使用 includes 会报错。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号