【问题标题】:Can't retrieve file from S3 with Rails Active Storage无法使用 Rails Active Storage 从 S3 检索文件
【发布时间】:2020-08-04 22:15:35
【问题描述】:

我正在尝试使用 Rails Active Storage 将照片上传到 S3。

我可以附上一张照片:

user.photo.attach(io: File.open('spec/images/filename.png'), filename: 'filename.png')

我可以保存用户,我可以获取照片服务 url 并在浏览器和我的存储桶中看到它:

user.photo.service_url

但是,如果我重新启动控制台并尝试获取服务 url,我会收到以下错误:

Module::DelegationError (service_url delegated to attachment, but attachment is nil)

这是我的存储桶设置:

storage.yml:

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-2
  bucket: <%= Rails.application.credentials.dig(:aws, :bucket) %>

应用程序.rb:

config.active_storage.service = :amazon

user.rb:

has_one_attached :photo

我在 storage.yml 文件中使用 public: true 时也遇到了问题。

如果我尝试设置配置,我会收到以下错误:

ArgumentError (Cannot load `Rails.config.active_storage.service`:)
invalid configuration option `:public'
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-2
  bucket: <%= Rails.application.credentials.dig(:aws, :bucket) %>
  public: true

【问题讨论】:

  • 你是否也在config/environments/development.rbconfig/environments/production.rb文件中设置了config.active_storage.service = :amazon
  • 考虑使用Rails.application.credentials.fetch(:aws).fetch(:access_key_id)而不是dig,如果它在启动时不存在而不是在使用时会引发错误,这对调试非常有帮助。

标签: ruby-on-rails amazon-s3 rails-activestorage


【解决方案1】:

我还想将我的文件上传到 AWS S3,并公开发布。

我也遇到了这个问题,发现如下:

ArgumentError (Cannot load `Rails.config.active_storage.service`:)
invalid configuration option `:public'

来自this file in the aws-sdk-ruby gem。根据错误消息,aws-sdk-ruby gem 不支持public: true 选项。

我使用了以下解决方法(特别感谢this article):

  1. 我将 storage.yml 更新为:
public_amazon:
  service: S3
  access_key_id: some_key
  secret_access_key: some_secret
  bucket: some-bucket-name
  region: some-region
  upload:
    acl: "public-read"

以上设置上传文件权限为公开。

  1. 这样检索公共 URL:
user.photo.attach(params[:file])
url = user.photo.service.send(:object_for, user.photo.key).public_url

【讨论】:

  • 正如对此answer 的评论中提到的,在这种情况下调用send 是不好的做法。 user.photo.service_url.sub(/\?.*/, '') 产生相同的结果,而无需调用 other answer 中提到的服务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-30
  • 2020-11-04
  • 2019-07-18
  • 2019-11-19
  • 2018-11-26
  • 2022-11-11
相关资源
最近更新 更多