按活动存储中的文件名排序多个图像 Rails 5.2

Order multiple images by filename in Active storage Rails 5.2

我在 Post 模型中有 has_many_attached 个图像关系。在 Post 显示页面上显示图像时,我想按文件名对图像进行排序。如何按文件名排序?

示例:

<% @post.images.order("id DESC").each do |image| %>

是否可以通过 active_storage_blob.filename 之类的方式按文件名排序?

当您将 has_many_attached 宏添加到 class 时,它实际上将以下关系添加到您的 class

  class Post < ApplicationRecord
     has_many :image_attachments, -> { where(name: 'image') }, class_name: "ActiveStorage::Attachment", as: :record, inverse_of: :record, dependent: false
     has_many :image_blobs, through: :image_attachments, class_name: "ActiveStorage::Blob", source: :blob
  end

这意味着我们可以利用关系来处理 filename 的排序,这实际上是 ActiveStorage::Blob 的属性而不是附件。为此,我们参考您的案例中宏 images 定义的关系,然后 join 参考其与 ActiveStorage::Blob 的自然关系,以便我们可以根据这些字段进行排序。

最终结果会是

   <% @post.images.joins(:blobs).order('active_storage_blobs.filename ASC').each do |image| %>

现在所有图像都将按文件名排序,但是由于连接实际上不会加载任何数据,我假设您在视图中引用文件名,我们也可以使用

   <% @post.images.includes(:blobs).references(:blobs).order('active_storage_blobs.filename ASC').each do |image| %>

使用一个查询同时加载图像和 ActiveStorage::Blob 数据,以避免原始版本可能出现的 n + 1 个问题。

如果您有 class ActiveStorage 设置,例如:

class Post < ApplicationRecord
  has_many_attached :images
end

您可以运行这个来订购并避免 N+1 查询

@post.images.includes(:blob).references(:blob).order(:filename)

对于Rails 6 我需要

@post.images.includes(:blob).references(:blob).order('active_storage_blobs.filename ASC').each do |image|
  # ...
end

如果有人在谷歌上搜索 general 解决方案如何重新排序 has_many_attached 附件,您可以通过向模型中添加一个 Array/JSON-Array/Serialized 字段来声明has_many_attached 并按顺序存储 ActiveStorage::Attachment 的 ID。然后你可以这样做:

# app/models/entry.rb
class Entry < ApplicationRecord
  has_many_attached :pictures


  def ordered_pictures
    pictures.sort_by{ |pic| ordered_picture_ids.index(pic.id) || (pic.id*100) }
  end

  def ordered_picture_ids=(ids)
    super(ids.map(&:to_i)) # convert any ids passed to this method to integer
                           # this is just for security reasons,
                           # you don't need to do this for the feature to work
  end
end

如果你不明白我的意思,我写了更详细的文章:https://blog.eq8.eu/article/order-attachments-in-rails-activestorage-has_many_attached.html