Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to directly save this file to ActiveStorage?

I am using a ruby gem for gpx parsing and editing. I want to store the edited result in active storage.

The gem has this method for saving

    def write(filename, update_time = true)
      @time = Time.now if @time.nil? || update_time
      @name ||= File.basename(filename)
      doc = generate_xml_doc
      File.open(filename, 'w+') { |f| f.write(doc.to_xml) }
    end 

And ActiveStorage has an example for saving

@message.image.attach(io: File.open('/path/to/file'), filename: 'file.pdf')

I could use both of these and it should work but then I am writing the file twice as well as having a an extra unneeded file sitting on the filesystem that needs to be manually removed later.

The ideal situation would be to have the gpx gem directly pass the data to ActiveStorage and let AS be the only one saving the file.

Given write() seems to be the only way to export/save the data and generate_xml_doc is a private method, is there any way I can achieve this without forking the gem or monkey patching it?

like image 617
Qwertie Avatar asked Oct 16 '25 22:10

Qwertie


1 Answers

Looking at the gem documentation, looks like you don't need to use the write method but instead use to_s method which should create the xml string which you can then use Tempfile to upload with active storage:

Here's the to_s method

def to_s(update_time = true)
  @time = Time.now if @time.nil? || update_time
  doc = generate_xml_doc
  doc.to_xml
end

#so assuming you have something like this:

bounds = GPX::Bounds.new(params)

file = Tempfile.new('foo')
file.path      # => A unique filename in the OS's temp directory,
               #    e.g.: "/tmp/foo.24722.0"
               #    This filename contains 'foo' in its basename.
file.write bounds.to_s
file.rewind    
@message.image.attach(io: file.read, filename: 'some_s3_file_name.xml') 
file.close
file.unlink    # deletes the temp file

UPDATED (thanks @Matthew):

But you may not even need the tempfile, this will probably work

bounds = GPX::Bounds.new(params)
@message.image.attach(io: StringIO.new(bounds.to_s),  name: 'some_s3_file_name.xml') 
like image 156
lacostenycoder Avatar answered Oct 19 '25 11:10

lacostenycoder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!