Rails:无法将图像解析为 URL:to_model 委托给附件,但附件为零 Rails 5.2

Posted

技术标签:

【中文标题】Rails:无法将图像解析为 URL:to_model 委托给附件,但附件为零 Rails 5.2【英文标题】:Can't resolve image into URL: to_model delegated to attachment, but attachment is nil in Rails 5.2 【发布时间】:2019-06-08 22:04:09 【问题描述】:

我有以下表格:

<%= form_with(model: user, local: true) do |form| %>
  <% if user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>

      <ul>
      <% user.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.file_field :avatar %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

在我的edit 页面上调用它:

<h1>Upload Avatar</h1>
  <%= image_tag(@user.avatar) %>
  <%= render 'form', user: @user %>
<hr>

我收到标题中的错误,但我不确定为什么头像没有附加到 user 模型。我已经完成了active_storage 的所有要求。

has_one_attached :avataruser model

user controller:

  def identity_params
    params.permit(:email_confirmation, :password, :password_confirmation, :avatar).to_h.symbolize_keys.tap do |params|
      params[:email] = params[:email_confirmation]
    end 
  end 

我还有所有必要的迁移。我错过了实际的头像附加逻辑吗?

【问题讨论】:

【参考方案1】:

如果您尝试在视图中显示不存在的附件,您可能会收到错误消息“无法将图像解析为 URL:to_model 委托给附件,但附件为零”

<%= image_tag(@user.avatar) %>

为避免错误,您应该这样做:

<%= image_tag(@user.avatar) if @user.avatar.attached? %>

【讨论】:

感谢您的回复。我的意思是我不确定为什么它不将头像保存到数据库中。 问题在于controller 中没有user.avatar.attach(params['user']['avatar']) 您使用的是哪种存储方式?本地还是云端?云存储可能与CORS 存在一些问题。您的浏览器控制台中是否出现任何错误? @A.J 在哪个控制器中?在用户控制器中? BTW github.com/rails/rails/issues/35613 我在开发过程中随机面临这个问题,即使记录已正确附加文件,我可以看到在活动存储表中进行了插入,但它以某种方式丢失了附件稍后的。它发生在一些随机记录上,而不是每条记录上。【参考方案2】:

您似乎缺少配置(因为您没有提及):

您必须在 config/storage.yml 中声明 Active Storage 服务

来自文档的示例:

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

amazon:
  service: S3
  access_key_id: ""
  secret_access_key: ""

你必须通过设置Rails.application.config.active_storage.service告诉Active Storage使用哪个服务

由于每个环境可能会使用不同的服务,因此建议在每个环境的基础上执行此操作。要在开发环境中使用上一个示例中的磁盘服务,您需要将以下内容添加到config/environments/development.rb

# Store files locally.
config.active_storage.service = :local

【讨论】:

如果设置好了,我就拥有了。对不起,我忘了提。 我正在升级现有的应用程序。这里没有这样的设置。我发现这个答案很有用。【参考方案3】:

Soultion 如果您的用户模型 ID 是 UUID

您需要通过record 字段将type: :uuid 添加到ActiveStorage 迁移中来稍微修改ActiveStorage 迁移

create_table :active_storage_attachments do |t|
  t.string     :name,     null: false
  t.references :record,   null: false, polymorphic: true, index: false, type: :uuid
  ...

参考https://edgeguides.rubyonrails.org/active_storage_overview.html#setup

【讨论】:

【参考方案4】:

由于愚蠢的错误,我也面临同样的错误。实际上我在 local: 键中添加了额外的空间。因此,请确保您遵循正确的缩进。并且不应该错过配置。您必须通过以下方式在 config/storage.yml 中声明 Active Storage 服务。

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

amazon:
  service: S3
  access_key_id: ""
  secret_access_key: ""
  bucket: ""
  region: "" # e.g. 'us-east-1'

确保在 environment/development.rb、environment/production.rb 和 environment/test.rb 中添加了以下代码行

config.active_storage.service = :local #environment/development.rb
config.active_storage.service = :amazon ##environment/production.rb
config.active_storage.service = :test #environment/test.rb

【讨论】:

以上是关于Rails:无法将图像解析为 URL:to_model 委托给附件,但附件为零 Rails 5.2的主要内容,如果未能解决你的问题,请参考以下文章

Mechanize Rails - Web Scraping - 服务器使用JSON进行响应 - 如何将URL解析为下载CSV

将远程 HTML 中的图像 URL 解析为 JSON

如何使用 Rails 主动存储从 url 保存图像?

如何从 Rails Active Storage 中的 url 附加图像

从 C# 中的属性获取图像 URL

Rails:从URL解析路由信息