Rails 5.2 Active Storage添加自定义属性

pax*_*xer 18 ruby ruby-on-rails rails-activestorage

我有一个带附件的模型:

class Project < ApplicationRecord
  has_many_attached :images
end
Run Code Online (Sandbox Code Playgroud)

当我附加并保存图像时,我还想保存附加图像的附加自定义属性 - display_order(整数).我想用它来对附加的图像进行排序,并按照我在此自定义属性中指定的顺序显示它们.我已经查看了#attach方法和ActiveStorage::Blob模型的ActiveStorage源代码,但看起来没有内置方法来传递一些自定义元数据.

我想知道,使用ActiveStorage解决这个问题的惯用方法是什么?在过去,我通常只会display_order在ActiveRecord模型中添加一个属性来表示我的附件,然后将其与.order(display_order: :asc)查询一起使用.

Geo*_*orn 20

如果您需要为每个图像存储其他数据并根据该数据执行查询,我建议您提取一个Image包装附件的模型file:

# app/models/project.rb
class Project < ApplicationRecord
  has_many :images, dependent: :destroy
end
Run Code Online (Sandbox Code Playgroud)
# app/models/image.rb
class Image < ApplicationRecord
  belongs_to :project

  has_one_attached :file
  delegate_missing_to :file

  scope :positioned, -> { order(position: :asc) }
end
Run Code Online (Sandbox Code Playgroud)
<%# app/views/projects/show.html.erb %>
<% @project.images.positioned.each do |image| %>
  <%= image_tag image %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

请注意,上面的示例视图会对具有N个图像的项目(项目图像的一个查询,每个图像的ActiveStorage::Attachment记录的另一个查询以及每个附加的一个查询)产生2N + 1个查询ActiveStorage::Blob.为了清晰起见,我故意避免优化查询数量.

  • @Richard,您可以使用`ActiveRecord :: Base#includes`和`#incin`来定义您自己的`with_attached_images`范围.这是一个更全面的例子:https://gist.github.com/georgeclaghorn/9baf3b9f1796eed5a983d35825b7f86c (5认同)