如何按 ActiveStorage 附件名称排序 collection?

How to order collection by ActiveStorage attachment name?

我需要按 2 个属性订购 collection。一个是常规属性,我称之为 attr,另一个是 ActiveStorage 附件的名称。问题是,由于 ActiveStorage 定义关系的方式,我无法加入其 table 以按其属性之一进行排序。

这大致就是我要尝试做的事情:

class Document < ApplicationRecord
  has_one_attached :file

  scope :sorted, -> { joins(:file).order(attr: :asc, 'files.filename': :asc) }
end

我知道 files 不是 table 的名称,这只是一个例子。我弄乱了 ActiveStorage 的 table 名称,甚至尝试用 ActiveStorage::Attachment 和 ActiveStorage::Blob 手动定义关系但没有成功。

关于如何实现这一点有什么想法吗?

要订购数据库服务器上的文档,您可以通过附件加入 blob:

class Document < ApplicationRecord
  has_one_attached :file
  scope :ordered_by_filename, -> { joins(file_attachment: :blob).order("active_storage_blobs.filename ASC") }
end

或者,非规范化以提高性能。在文档 table:

中保留文件名的副本
class Document < ApplicationRecord
  has_one_attached :file
  before_save { self.filename ||= file.filename }
  scope :ordered_by_filename, -> { order(filename: :asc) }
end

最后,考虑在应用程序中尽可能进行排序。 (分页是一种可能 可行的情况。)在考虑可伸缩性的情况下,水平扩展应用程序服务器池通常比扩展数据库更容易:

class Document < ApplicationRecord
  has_one_attached :file
  delegate :filename, to: :file

  def self.ordered_by_filename
    # Use the with_attached_files scope to avoid N+1 queries.
    with_attached_files.sort_by(&:filename)
  end
end