如何获取 ActiveStorage 属性列表(附件名称)?

How to get list of ActiveStorage attributes (attachment names)?

例如我有模型

class User < ApplicationRecord
  has_one_attached :avatar
  has_one_attached :diploma

  has_many_attached :photos
  has_many_attached :files
end

如何获取某些型号的附件名称列表(分别针对 has_one_attachedhas_many_attached)?

[:avatar, :diploma][:photos, :files] 在这种情况下。

我不知道有没有直接的方法,老兄这应该是解决方法(对于已经存储的记录):

ActiveStorage::Attachment.distinct.pluck(:record_type).map(&:underscore)


从模型开始,这是一个待完善的原始想法:

User.reflect_on_all_associations(:has_many).map { |e| e.name.to_s.split("_") }.select { |e| e.last == "attachments" }
User.reflect_on_all_associations(:has_one).map { |e| e.name.to_s.split("_") }.select { |e| e.last == "attachment" }

注意 == "attachments"== "attachment"

@iGian 给了一个很好的idea,但是里面有个问题

如果附件名称包含下划线,将导致结果不正确。

所以我的解决方案是:

  • 对于has_many_attached
User.
  reflect_on_all_associations(:has_many).
  map { |reflection| reflection.name.to_s }.
  select { |name| name.match?(/_attachments/) }.
  map { |name| name.chomp('_attachments').to_sym }

#=> [:photos, :files]
  • 对于has_one_attached
User.
  reflect_on_all_associations(:has_one).
  map { |reflection| reflection.name.to_s }.
  select { |name| name.match?(/_attachment/) }.
  map { |name| name.chomp('_attachment').to_sym }

#=> [:avatar, :diploma]

一个不依赖于命名约定的解决方案,将根据 Rails 自己的内部结构为您提供您所需要的内容:

  • 对于has_one_attached
User
  .reflect_on_all_attachments
  .filter { |association| association.instance_of? ActiveStorage::Reflection::HasOneAttachedReflection }
  .map(&:name)
  • 对于has_many_attached
User
  .reflect_on_all_attachments
  .filter { |association| association.instance_of? ActiveStorage::Reflection::HasManyAttachedReflection }
  .map(&:name)