简体   繁体   English

Rails 5.2 Active Storage 添加自定义属性

[英]Rails 5.2 Active Storage add custom attributes

I have a model with attachments:我有一个带附件的模型:

class Project < ApplicationRecord
  has_many_attached :images
end

When I attach and save the image I also want to save an additional custom attribute - display_order (integer) with the attached image.当我附加并保存图像时,我还想保存附加的自定义属性 - display_order (整数)和附加的图像。 I want to use it to sort the attached images and display them in the order I specified in this custom attribute.我想用它对附加的图像进行排序,并按照我在此自定义属性中指定的顺序显示它们。 I've reviewed ActiveStorage source code for #attach method as well as ActiveStorage::Blob model but it looks like there is no built in method to pass some custom metadata.我已经查看了#attach方法以及ActiveStorage::Blob模型的 ActiveStorage 源代码,但似乎没有内置方法来传递一些自定义元数据。

I wonder, what's the idiomatic way to solve this problem with ActiveStorage?我想知道,用 ActiveStorage 解决这个问题的惯用方法是什么? In the past I would usually just add a display_order attribute to the ActiveRecord model which represents my attachment and then simply use it with .order(display_order: :asc) query.在过去,我通常只向 ActiveRecord 模型添加一个display_order属性,它代表我的附件,然后简单地将它与.order(display_order: :asc)查询一起使用。

If you need to store additional data with each image and perform queries based on that data, I'd recommend extracting an Image model that wraps an attached file :如果你需要存储额外数据与每个图像并基于该数据的查询,我建议你抽取的Image ,它包装附加模型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
<%# app/views/projects/show.html.erb %>
<% @project.images.positioned.each do |image| %>
  <%= image_tag image %>
<% end %>

Note that the example view above causes 2N+1 queries for a project with N images (one query for the project's images, another for each image's ActiveStorage::Attachment record, and one more for each attached ActiveStorage::Blob ).请注意,上面的示例视图会导致对具有 N 个图像的项目进行 2N+1 次查询(对项目图像进行一次查询,对每个图像的ActiveStorage::Attachment记录进行一次查询,对每个附加的ActiveStorage::Blob多次查询)。 I deliberately avoided optimizing the number of queries for clarity's sake.为了清楚起见,我故意避免优化查询数量。

If you simply need to order the images, you could customize the filename and order the images by filename.如果您只需要对图像进行排序,则可以自定义文件名并按文件名对图像进行排序。 I use the down gem which I highly recommend.我使用我强烈推荐的羽绒宝石。

For example:例如:

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

then in your controller for @object:然后在@object 的控制器中:

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

then in your view for @object然后在你看来@object

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM