Attach attributes to has_many_attached ActiveStorage

1

When Attach multiple files to a certain model, I think it's common to use has_many_attached in ActiveStorage, At this time,

  • I want to add attributes to a file
  • I want to delete a file with the same attributes if it already exists.

I think it will overflow with feelings.

So I'll do it.

class Foo < ApplicationRecord
  has_many_attached :bars
end

attach something in this class

class Foo < ApplicationRecord
  has_many_attached :bars
  def attach_bars
    bar = 'something' #何らか適当なファイル的なやつ
    bars.attach(
      io: StringIO.new(bar),
      filename: 'なんらかてきとうなふぁいるめい.txt',
      content_type: 'text/plain',
      metadata: { bar_type: 'something' }
    )
  end
end

The metadata: { bar_type: 'something' } part is something nice and this will keep the data in a "bar_type": "something" way to active_storage_blobs.metadata. You did it.

Now that you have added attributes, if you want to remove the bar_type == 'something' attachment in the bars, you can use

foo = Foo.find(xxx)
foo.bars.select {|bar| bar.metadata[:bar_type] == 'something' }
  .each {|bar| bar.purge }

I can purge like that, but if bars gets 100 or 200 cases, it would be a fluke, so I wanted to narrow it down by query in advance.

So, I did.

foo.bars.joins(:blob).where(
  "`active_storage_blobs`.`metadata`->>'$.bar_type' = ?", 'something'
).each { |bar| bar.purge }

You did it!

Share:
1
yamaguchi takayuki
Author by

yamaguchi takayuki

Updated on November 29, 2019