如何在活动存储中查找用户附件的总大小
How to find total size of user attachments in active storage
我正在使用 Rails 6。
如何获取活动存储中用户附件的总大小?
======
更新:
如果我有用户A和用户B
如何获取用户A附件的总大小?
如果你想获得 所有附件的大小 与某些记录相关联(例如 user = User.first
)你可以使用这个:
ActiveStorage::Attachment.where(record: user).map(&:byte_size).sum
或使用此类查询更高效
ActiveStorage::Attachment.joins(:blob).where(record: user).sum(:byte_size)
或者像这样
ActiveStorage::Blob.
joins(:attachments).
where(active_storage_attachments: { record_id: user.id, record_type: user.class.name }).
sum(:byte_size)
例如这个用户has_many_attached :images
在这种情况下,您只能获取此用户的 所有图像 的大小:
user.images.map(&:byte_size).sum
或使用此类查询更高效
user.images.joins(:blob).sum(:byte_size)
或者像这样
user.images_blobs.sum(:byte_size)
使用 include ActionView::Helpers::NumberHelper
您可以将字节大小(整数)转换为人类格式:
number_to_human_size(size_of_all_attachments)
根据@Yshmarov 和@mechnicov 的回答,我是这样做的
模型中
after_create_commit :add_user
private
def add_user
files.attachments.update(user_id: self.user.id)
end
在控制器中
@checksize = ActiveStorage::Blob.where(id: current_user.id).map(&:byte_size).sum
可见
<%= number_to_human_size(@checksize) %>
这不是问题的解决方案;但这帮助我解决了自己的案子。所以我发布它可能会帮助其他人,因为我认为我的情况很常见。
如果你有这个嵌套结构:
class Album < ApplicationRecord
has_many :album_items, dependent: :destroy
end
class AlbumItem < ApplicationRecord
belongs_to :album, counter_cache: :album_items_count
before_destroy :purge_attachment
has_one_attached :photo # automatically adds a `with_attached_photo` scope to prevent n+1 queries
private
def purge_attachment
photo.purge_later
end
end
计算相册总大小:
Album.first.album_items.with_attached_photo.map { |album_item| album_item.photo.byte_size }.sum
注意添加的 with_attached_photo
范围,以防止 n+1 查询。
你可以直接在数据库上做,这比这里发布的其他答案要高效得多。
假设你的 User
has_many_attached :images
.
查找一个用户图像的大小
您可以通过以下方式找到一个用户图片的总大小:
size_of_all_attachments = user.images_blobs.sum("active_storage_blobs.byte_size")
然后,正如 mechnicov 指出的那样,您可以包含 ActionView::Helpers::NumberHelper
以将字节大小(整数)转换为人类格式:
number_to_human_size(size_of_all_attachments)
查找所有用户图像的大小
也很轻松:
User.joins(:images_blobs).sum("active_storage_blobs.byte_size")
它的工作方式与 per the documentation 一样,has_many_attached
宏实际上在您的用户模型中创建了两个关联,就像您自己声明它们一样:
has_many :images_attachments, ...
has_many :images_blobs
这些 :images_blobs
是名为 ActiveStorage::Blob
的常规 ActiveRecord 模型,其中 table 名称为 active_storage_blob
并且它们包含一个名为 byte_size
的列,其中类型 :bigint
,包含字节大小。
此处的其他答案建议使用 ActiveStorage::Attachment.where(record: User.first).map(&:byte_size).sum
。但是,由于以下两个原因,这效率不高:
它将首先return所有ActiveStorage::Attachment
模型;这些是 Rails 用来将您的 User
模型连接到 ActiveStorage::Blob
模型的连接模型,后者实际上包含我们之后的 byte_size
列。调用 ActiveStorage::Attachement#byte_size
会起作用,但由于 ActiveStorage::Attachment
上的 delegate_missing_to :blob
声明,所以它会使用 method_missing
,这要慢得多。
由于 #1,由于 ActiveStorage::Attachment
没有 byte_size
列,它正在调用 .map
,创建一个不必要的数组并加载和实例化所有这些模型是不必要的。
所以,这个答案直接进入数据库并询问已经在那里等你的总和。
我正在使用 Rails 6。 如何获取活动存储中用户附件的总大小?
======
更新:
如果我有用户A和用户B
如何获取用户A附件的总大小?
如果你想获得 所有附件的大小 与某些记录相关联(例如 user = User.first
)你可以使用这个:
ActiveStorage::Attachment.where(record: user).map(&:byte_size).sum
或使用此类查询更高效
ActiveStorage::Attachment.joins(:blob).where(record: user).sum(:byte_size)
或者像这样
ActiveStorage::Blob.
joins(:attachments).
where(active_storage_attachments: { record_id: user.id, record_type: user.class.name }).
sum(:byte_size)
例如这个用户has_many_attached :images
在这种情况下,您只能获取此用户的 所有图像 的大小:
user.images.map(&:byte_size).sum
或使用此类查询更高效
user.images.joins(:blob).sum(:byte_size)
或者像这样
user.images_blobs.sum(:byte_size)
使用 include ActionView::Helpers::NumberHelper
您可以将字节大小(整数)转换为人类格式:
number_to_human_size(size_of_all_attachments)
根据@Yshmarov 和@mechnicov 的回答,我是这样做的
模型中
after_create_commit :add_user
private
def add_user
files.attachments.update(user_id: self.user.id)
end
在控制器中
@checksize = ActiveStorage::Blob.where(id: current_user.id).map(&:byte_size).sum
可见
<%= number_to_human_size(@checksize) %>
这不是问题的解决方案;但这帮助我解决了自己的案子。所以我发布它可能会帮助其他人,因为我认为我的情况很常见。
如果你有这个嵌套结构:
class Album < ApplicationRecord
has_many :album_items, dependent: :destroy
end
class AlbumItem < ApplicationRecord
belongs_to :album, counter_cache: :album_items_count
before_destroy :purge_attachment
has_one_attached :photo # automatically adds a `with_attached_photo` scope to prevent n+1 queries
private
def purge_attachment
photo.purge_later
end
end
计算相册总大小:
Album.first.album_items.with_attached_photo.map { |album_item| album_item.photo.byte_size }.sum
注意添加的 with_attached_photo
范围,以防止 n+1 查询。
你可以直接在数据库上做,这比这里发布的其他答案要高效得多。
假设你的 User
has_many_attached :images
.
查找一个用户图像的大小
您可以通过以下方式找到一个用户图片的总大小:
size_of_all_attachments = user.images_blobs.sum("active_storage_blobs.byte_size")
然后,正如 mechnicov 指出的那样,您可以包含 ActionView::Helpers::NumberHelper
以将字节大小(整数)转换为人类格式:
number_to_human_size(size_of_all_attachments)
查找所有用户图像的大小
也很轻松:
User.joins(:images_blobs).sum("active_storage_blobs.byte_size")
它的工作方式与 per the documentation 一样,has_many_attached
宏实际上在您的用户模型中创建了两个关联,就像您自己声明它们一样:
has_many :images_attachments, ...
has_many :images_blobs
这些 :images_blobs
是名为 ActiveStorage::Blob
的常规 ActiveRecord 模型,其中 table 名称为 active_storage_blob
并且它们包含一个名为 byte_size
的列,其中类型 :bigint
,包含字节大小。
此处的其他答案建议使用 ActiveStorage::Attachment.where(record: User.first).map(&:byte_size).sum
。但是,由于以下两个原因,这效率不高:
它将首先return所有
ActiveStorage::Attachment
模型;这些是 Rails 用来将您的User
模型连接到ActiveStorage::Blob
模型的连接模型,后者实际上包含我们之后的byte_size
列。调用ActiveStorage::Attachement#byte_size
会起作用,但由于ActiveStorage::Attachment
上的delegate_missing_to :blob
声明,所以它会使用method_missing
,这要慢得多。由于 #1,由于
ActiveStorage::Attachment
没有byte_size
列,它正在调用.map
,创建一个不必要的数组并加载和实例化所有这些模型是不必要的。
所以,这个答案直接进入数据库并询问已经在那里等你的总和。