【问题标题】:Order multiple images by filename in Active storage Rails 5.2在 Active storage Rails 5.2 中按文件名排序多个图像
【发布时间】:2023-04-09 12:50:01
【问题描述】:

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

例子:

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

是否可以通过诸如 active_storage_blob.filename 之类的文件名进行排序?

【问题讨论】:

  • 也许你可以试试post.images.joins(:blob).order('active_storage_blobs.filename ASC')
  • 完美@engineersmnky。需要升级我的加入游戏。那行得通。公平竞争。让它成为一个答案,我会确认它是正确的,伙计。谢谢。

标签: ruby-on-rails rails-activestorage


【解决方案1】:

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

  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 个问题。

【讨论】:

  • 我认为现在类似于@post.images_attachments.joins(:blob)...
【解决方案2】:

我需要 Rails 6

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

【讨论】:

    【解决方案3】:

    如果您使用 ActiveStorage 设置类,例如:

    class Post < ApplicationRecord
      has_many_attached :images
    end
    

    您可以运行此命令并避免 N+1 查询

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

    【讨论】:

      【解决方案4】:

      如果有人在谷歌上搜索 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

      【讨论】:

        猜你喜欢
        • 2019-11-01
        • 2019-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-14
        相关资源
        最近更新 更多