首页 > 解决方案 > 在 active_storage_attachments 上设置 record_type 的 ActiveStorage 问题

问题描述

我有 ActiveStorage 的问题

情况是我有一个名为的模型,并且上传过程成功的表和附件Setting::Profile名称 ,但是什么时候无法找到获取图片,因为在表中的属性中存储了名称,应该是名称Admin:avataractive_storage_attachmentsrecord_typeSetting::ProfileAdmin

如何添加一行来准备record_type属性?谢谢

这是我的演示:https ://github.com/SunDi3yansyah-forks/AppActiveStorage

截图来自 2018-07-11 01-24-48

标签: ruby-on-railsrubyamazon-s3ruby-on-rails-5.2

解决方案


我发现了这个问题(在控制台中尝试)。

如果你设置profile = Account::Profile.last然后调用profile.avatar.attached?它返回false。record_type这是因为中的列ActiveStorage::Attachment设置为用户。

因此,您无法访问 blob,因为profile.avatar.blob返回以下查询:

SELECT  "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = ? AND "active_storage_attachments"."record_type" = ? AND "active_storage_attachments"."name" = ? LIMIT ?  [["record_id", 1], ["record_type", "Account::Profile"], ["name", "avatar"], ["LIMIT", 1]]

和错误:Module::DelegationError: blob delegated to attachment, but attachment is nil

我发现的一种可能的解决方法是定义 Account::Profile 如下:

class Account::Profile < ApplicationRecord
    self.table_name = "users"
    # has_one_attached :avatar # remove this

  def avatar
    ActiveStorage::Attachment.where(name: :avatar, record_type: 'User', record_id: self.id).last
  end

end

这适用于显示图像,但问题profile.avatar.class不是ActiveStorage::Attached::One(如User.last.avatar.class)而是ActiveStorage::Attachment

因此,您不能.attached?在其上调用示例方法。您必须使用profile.avatar.present?来检查头像是否存在。

一个可能更好的解决方案是这样定义实例方法avatar:

def avatar
  ActiveStorage::Attached::One.new('avatar', User.find(id), dependent: :purge_later)
end

需要实例化一个对象,ActiveStorage::Attached::One但记录必须是User类(匹配record_type),这就是为什么User.find(id)。现在所有方法都可用:profile.avatar.methods.


推荐阅读