Ruby on Rails - 主动存储 - 无法使用 image_tag 显示图像,但可以使用 <img src=model.attachment.url>?

问题描述 投票:0回答:1

我最近一直在尝试实现 Ruby on Rails 的 ActiveStorage。我的设置非常简单,但我在使用

<%= image_tag...
处理我上传的文件时遇到问题。我正在从 AWS S3 中提供文件。这是我的测试设置:
storage.yml

# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
amazon:
  service: S3
  # Instad of specifying these or using Rails.application.credentials we can rely on env vars or any other valid way of authenticating the aws sdk gem
  access_key_id:     # Hard coded creds right now for testing
  secret_access_key: # Hard coded creds right now for testing
  region: us-east-1
  bucket: test-my-s3-bucket-name

我一直在使用名为

personnel

的模型进行测试
class Personnel < ApplicationRecord
  ...
  # NEW ACTIVESTORAGE CODE
  has_one_attached :as_photo
  # OPTIONAL:
  validates :as_photo, size: { less_than: 3.megabytes , message: 'is too large' },
                       content_type: {in: ['image/jpeg', 'image/png', 'image/gif', 'image/pjpeg', 'image/x-png'],
                                      message: I18n.t("errors.file_invalid_format", :formats => "JPG,GIF,PNG") }

  before_save :define_attachment_key
  # This method will generate a string based on the model name
  # This string is used in the file's key name on S3. This is how we place files into s3 "sub folders" for organizational/browsing purposes
  def photo_path
    # This key has to be unique across all assets which is why we call ActiveRecord::SecureToken.generate_unique_secure_token
    # modelname/uuid but you could create further subdivisions if you wanted. modelname/attachment1/uuid & modelname/attachment2/uuid for example
    "public/#{Rails.env}/models/#{self.class.name}/photo/#{ActiveStorage::Blob.generate_unique_secure_token}"
  end

  def define_attachment_key
    as_photo.key = photo_path if as_photo.new_record?
    # add any additional ..._path methods here if there are multiple attachments on this model you want subfolders for.
    # Attachments without a ..._path method will placed at the root of the bucket
  end

然后我有一个指向此模板的测试路线

<h1>Personnel</h1>
<h2>There are a total of <%= @count %> Personnel records</h2>

<ul>
  <% @persons.each do |person| %>
    <li>
      <%= person.id %>
      <% if person.as_photo.present? %>
        <ul>
          <li>
              <%= image_tag(person.as_photo) %>
          </li>
          <li>
            Proxy: <%= image_tag rails_storage_proxy_path(person.as_photo) %>
          </li>
          <li>
            img tag with as.url: <img src="<%= person.as_photo.url %>" alt="an image wow">
          </li>
        </ul>
      <% end %>
    </li>
  <% end %>
</ul>

但是正如您所看到的,这 3 种渲染图像的方式中仅显示了一种 我认为不同方法提供的 URL 与此有关。

person.as_photo.url
url 看起来像一个预先签名的 AWS url,而仅使用
person.as_photo
和 image_tag 的其他 2 种方法(如文档使用中的示例)似乎会生成一个以某种方式首先通过 Rails 服务器路由的 URL,这些是那些不起作用的(404)。
 http://localhost:3000/rails/active_storage/blobs/proxy
&
http://localhost:3000/rails/active_storage/blobs/redirect

ruby-on-rails amazon-s3 rails-activestorage
1个回答
0
投票

明白了。 这个问题帮助我弄清楚了。显然,Activestorage 将其自己的路由附加到主路由文件中。如果您有一条包罗万象/通配符的路线可以捕获

rails/active_storage/...
(就像我所做的那样。
get '*path', to: ...
),那么您需要为
rails/active_storage
路线开辟一个例外。

© www.soinside.com 2019 - 2024. All rights reserved.