Rails 5.2 Active Storage添加自定义属性

时间:2018-03-27 10:14:38

标签: ruby-on-rails ruby rails-activestorage

我有一个带附件的模型:

class Project < ApplicationRecord
  has_many_attached :images
end

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

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

2 个答案:

答案 0 :(得分:13)

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

file
# app/models/project.rb
class Project < ApplicationRecord
  has_many :images, dependent: :destroy
end
# app/models/image.rb
class Image < ApplicationRecord
  belongs_to :project

  has_one_attached :file
  delegate_missing_to :file

  scope :positioned, -> { order(position: :asc) }
end

请注意,上面的示例视图会对包含N个图像的项目(项目图像的一个查询,每个图像的<%# app/views/projects/show.html.erb %> <% @project.images.positioned.each do |image| %> <%= image_tag image %> <% end %> 记录的另一个查询以及每个附加的ActiveStorage::Attachment的一个查询)进行2N + 1次查询)。为清晰起见,我故意避免优化查询次数。

答案 1 :(得分:0)

如果您只是需要对图像进行排序,您可以自定义文件名并按文件名对图像进行排序。我使用我强烈推荐的羽绒宝石。

例如:

image = Down.download(image_url)
filename = "description-#{order}"
@object.images.attach(io: image, filename: filename)

然后在@object 的控制器中:

@images = @object.images_attachments.joins(:blob).order('active_storage_blobs.filename ASC')

然后在您看来@object

<%@images.each do |image|%>
<%= image_tag image%>
<% end %>