我需要通过2个属性对集合进行排序。一个是常规属性,我将其称为attr
,另一个是ActiveStorage附件的名称。问题在于,由于ActiveStorage如何定义关系,我无法按其属性之一将其表连接起来进行排序。
这大概是我想要做的:
class Document < ApplicationRecord
has_one_attached :file
scope :sorted, -> { joins(:file).order(attr: :asc, 'files.filename': :asc) }
end
我知道files
不是表的名称,这只是一个示例。我搞砸了ActiveStorage的表名,甚至尝试通过ActiveStorage :: Attachment和ActiveStorage :: Blob手动定义关系,但没有成功。
关于如何实现这一目标的任何想法?
答案 0 :(得分:2)
要在数据库服务器上订购文档,您可以通过附件加入Blob:
class Document < ApplicationRecord
has_one_attached :file
scope :ordered_by_filename, -> { joins(file_attachment: :blob).order("active_storage_blobs.filename ASC") }
end
或者,对性能进行非规范化。在文件表中保留文件名的副本:
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