如何按 ActiveStorage 附件名称排序集合?

akz*_*z92 3 ruby-on-rails rails-activestorage

我需要按 2 个属性对集合进行排序。一个是常规属性,我将其命名attr为另一个属性,另一个是 ActiveStorage 附件的名称。问题是,由于 ActiveStorage 定义关系的方式,我无法连接其表以按其属性之一进行排序。

这大致就是我想要做的:

class Document < ApplicationRecord
  has_one_attached :file

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

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

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

Geo*_*orn 6

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

\n\n
class Document < ApplicationRecord\n  has_one_attached :file\n  scope :ordered_by_filename, -> { joins(file_attachment: :blob).order("active_storage_blobs.filename ASC") }\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者,为了性能而进行非规范化。在文档表中保留文件名的副本:

\n\n
class Document < ApplicationRecord\n  has_one_attached :file\n  before_save { self.filename ||= file.filename }\n  scope :ordered_by_filename, -> { order(filename: :asc) }\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
class Document < ApplicationRecord\n  has_one_attached :file\n  delegate :filename, to: :file\n\n  def self.ordered_by_filename\n    # Use the with_attached_files scope to avoid N+1 queries.\n    with_attached_files.sort_by(&:filename)\n  end\nend\n
Run Code Online (Sandbox Code Playgroud)\n