Rails 5.2 Active Storage 添加自定义属性
Rails 5.2 Active Storage add custom attributes
我有一个带附件的模型:
class Project < ApplicationRecord
has_many_attached :images
end
当我附加并保存图像时,我还想用附加图像保存一个额外的自定义属性 - display_order
(整数)。我想用它来对附加的图像进行排序,并按照我在此自定义属性中指定的顺序显示它们。我已经查看了 #attach
方法和 ActiveStorage::Blob
模型的 ActiveStorage 源代码,但看起来没有内置方法来传递一些自定义元数据。
我想知道,用 ActiveStorage 解决这个问题的惯用方法是什么?在过去,我通常只是将 display_order
属性添加到代表我的附件的 ActiveRecord 模型,然后简单地将它与 .order(display_order: :asc)
查询一起使用。
如果您需要为每个图像存储额外的数据并根据该数据执行查询,我建议提取一个 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 %>
请注意,上面的示例视图导致对包含 N 个图像的项目进行 2N+1 次查询(一次查询是针对项目的图像,另一次是针对每张图像的 ActiveStorage::Attachment
记录,另外一次是针对每个附加的 ActiveStorage::Blob
).为了清楚起见,我故意避免优化查询数量。
如果您只是需要排序图片,您可以自定义文件名并按文件名排序图片。我使用我强烈推荐的 gem。
例如:
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 %>
我有一个带附件的模型:
class Project < ApplicationRecord
has_many_attached :images
end
当我附加并保存图像时,我还想用附加图像保存一个额外的自定义属性 - display_order
(整数)。我想用它来对附加的图像进行排序,并按照我在此自定义属性中指定的顺序显示它们。我已经查看了 #attach
方法和 ActiveStorage::Blob
模型的 ActiveStorage 源代码,但看起来没有内置方法来传递一些自定义元数据。
我想知道,用 ActiveStorage 解决这个问题的惯用方法是什么?在过去,我通常只是将 display_order
属性添加到代表我的附件的 ActiveRecord 模型,然后简单地将它与 .order(display_order: :asc)
查询一起使用。
如果您需要为每个图像存储额外的数据并根据该数据执行查询,我建议提取一个 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 %>
请注意,上面的示例视图导致对包含 N 个图像的项目进行 2N+1 次查询(一次查询是针对项目的图像,另一次是针对每张图像的 ActiveStorage::Attachment
记录,另外一次是针对每个附加的 ActiveStorage::Blob
).为了清楚起见,我故意避免优化查询数量。
如果您只是需要排序图片,您可以自定义文件名并按文件名排序图片。我使用我强烈推荐的 gem。
例如:
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 %>