Можно ли напрямую сохранить этот файл в ActiveStorage? - PullRequest
0 голосов
/ 14 октября 2018

Я использую ruby ​​gem для разбора и редактирования gpx.Я хочу сохранить отредактированный результат в активном хранилище.

В геме есть этот метод для сохранения

    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 

, а в ActiveStorage есть пример для сохранения

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

Iможно использовать оба из них, и это должно сработать, но тогда я пишу файл дважды, а также имею дополнительный ненужный файл в файловой системе, который необходимо удалить позже.

Идеальной ситуацией будетпусть гем gpx напрямую передает данные в ActiveStorage, и пусть AS будет единственным, кто сохранит файл.

Учитывая, что write() кажется единственным способом экспорта / сохранения данных, а generate_xml_doc является частнымметод, есть ли способ, которым я могу достичь этого, не разветвляя драгоценный камень или обезьяна, исправляя его?

1 Ответ

0 голосов
/ 14 октября 2018

Глядя на документацию gem , похоже, что вам не нужно использовать метод write, а вместо этого используйте метод to_s, который должен создать строку xml, которую вы затем можете использовать Tempfile для загрузкис активным хранилищем:

Вот метод to_s

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

ОБНОВЛЕНО (спасибо @Matthew):

Но вам может даже не понадобиться временный файл, это, вероятно,работа

bounds = GPX::Bounds.new(params)
@message.image.attach(io: StringIO.new(bounds.to_s),  name: 'some_s3_file_name.xml') 
...