Rails 5.2 的 ActiveStorage 图像上传错误:signed_id 委托给附件,但附件为零

Posted

技术标签:

【中文标题】Rails 5.2 的 ActiveStorage 图像上传错误:signed_id 委托给附件,但附件为零【英文标题】:ActiveStorage Image Upload Error with Rails 5.2: signed_id delegated to attachment, but attachment is nil 【发布时间】:2019-02-24 06:07:10 【问题描述】:

我在使用 ActiveStorage 上传图像/pdf 时遇到问题。图片似乎可以毫无问题地上传,但是当我尝试显示它们时它们会导致错误。

我的blog 模型has_one_attached :imagehas_one_attached :pdf。以前可以上传(所以我知道我已经安装了 ActiveStorage 并且我的 amazon s3 设置正确),但是出了点问题。

唯一复杂的一点是,如果它有 PDF 文件,我需要它来工作(并非所有博客都有 pdf 文件......所有博客都应该有图片)。

我的blog#create方法是:

  def create
    @blog = Blog.new(blog_params)
    @blog.user_id = current_user.id
    if @blog.published
      @blog.published_on = DateTime.current
    end

    respond_to do |format|
      if @blog.save
        if @blog.image.attached?
          @blog.image.purge
        end
        @blog.image.attach(params[:image])
        if @blog.pdf.attached?
          @blog.pdf.purge
        end
        @blog.pdf.attach(params[:pdf])
        format.html  redirect_to @blog, notice: 'Blog was successfully created.' 
        format.json  render :show, status: :created, location: @blog 
      else
        format.html  render :new 
        format.json  render json: @blog.errors, status: :unprocessable_entity 
      end
    end
  end

我的blog#update方法是:

  def update
    if @blog.published
      @blog.published_on = DateTime.current
    end
    if @blog.image.attached?
      @blog.image.purge
    end
    @blog.image.attach(params[:image])
    if @blog.pdf.attached?
      @blog.pdf.purge
    end
    @blog.pdf.attach(params[:pdf])
    respond_to do |format|
      if @blog.update(blog_params)
        format.html  redirect_to @blog, notice: 'Blog was successfully updated.' 
        format.json  render :show, status: :ok, location: @blog 
      else
        format.html  render :edit 
        format.json  render json: @blog.errors, status: :unprocessable_entity 
      end
    end
  end

我的表格很简单:

<%= simple_form_for(@blog) do |f| %>
  <%= f.error_notification %>
  <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>

...
    <div class="form-group">
      <%= f.label "Blog Image" %><br />
      <%= f.file_field :image %>
    </div>
    <div class="form-group">
      <%= f.label "Linked PDF" %><br />
      <%= f.file_field :pdf %>
    </div>

...

  <div class="form-actions text-center">
    <%= f.button :submit, class: "btn-outline-primary" %>
  </div>
<% end %>

我正在尝试在博客中显示这样的图像:

<div class="frame" style="background-image: url(<%= rails_blob_url(@blog.image) %>)"></div>

PDF 是这样的:

<h2 class="cta text-center"><%= link_to @blog.cta, rails_blob_url(@blog.pdf), target: "_blank" %></h2>

我得到的错误是signed_id delegated to attachment, but attachment is nil 在图像被称为blog#show 页面上的背景图像的地方。如果有帮助,我会在 localhost 和 Heroku 上遇到同样的错误。

最后,我在this question 上看到了这个错误,并尝试删除并重新创建我的数据库,但无济于事。

谁能看到这里出了什么问题?

【问题讨论】:

你为什么要清除上传的图像然后重新附加它? 你能告诉我们完整的控制器代码吗?特别是强参数?另外,您是否将ActiveRecord::Base.include_root_in_json 设置为true 或false? 【参考方案1】:

我刚刚遇到了这个错误,真的很难弄清楚可能发生了什么。它首先出现在我提交表单并且不包含附件时。事实证明,我需要检查是否真的附加了某些东西并处理这种可能性。

也许尝试将 @blog.pdf.attach(params[:pdf]) 移到 blog#create 中的 respond_to 之前

然后,当尝试显示图像时,也许你可以尝试这样的事情

<% if blog.pdf.attached? == false %>
  <p>No pdf attached</p>
<% elsif blog.pdf.previewable? %>
  <%= link_to(image_tag(blog.pdf.preview(resize: "50x50>")),  rails_blob_path(blog.pdf, disposition: "attachment"))
%>
<% elsif blog.pdf.variable? %>
  <%= link_to(image_tag(blog.pdf.variant(resize: "50x50")), rails_blob_path(blog.pdf, disposition: "attachment"))%>
<% else %>
  <%= link_to "Download file", rails_blob_path(@blog.pdf, disposition: "attachment") %>
<% end %>

Heroku 在active storage here 上有一篇很好的文章,可能也会有所帮助。

【讨论】:

以上是关于Rails 5.2 的 ActiveStorage 图像上传错误:signed_id 委托给附件,但附件为零的主要内容,如果未能解决你的问题,请参考以下文章

上传前的 Rails 5.2 ActiveStorage 裁剪附件

如何在 Rails 5.2 中复制存储在 ActiveStorage 中的文件

Rails 5.2 的 ActiveStorage 图像上传错误:signed_id 委托给附件,但附件为零

如何在 Amazon S3 中自定义 Rails 5.2 ActiveStorage 附件的路径?

使用 Rails 5.2 ActiveStorage 创建和保存 pdf 并稍后附加到电子邮件

在 Rails 5.2 中禁用活动存储