I want to show a preview of presentation files on my website. I am trying to make a tempfile which reads from a Microsoft PowerPoint Open XML (.pptx) file stored in active storage.

I am using Docsplit.extract_images on the tempfile to convert the slides to images to show it as a preview in some form of image carousel.

I have slide parameterss such as [:name, :ppt, pages: [] ] where ppt is has_one_attached and pages is has_many_attached. This is what my slides_controller look like:

def create
    @slide = Slide.new(slide_params)

    respond_to do |format|
      if @slide.save
        tempfile = Tempfile.new([ 'foobar', '.pptx'])
        tempfile.binmode

        begin
          @slide.ppt.download { |chunk| tempfile.write(chunk) }
          tempfile.flush
          tempfile.rewind
        ensure
          tempfile.close!
        end
        @slide.pages << Docsplit.extract_images("#{tempfile.path}", :size => '1080x', :format => [:png])
        tempfile.unlink

        format.html { redirect_to slide_url(@slide), notice: "Slide was successfully created." }
        format.json { render :show, status: :created, location: @slide }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @slide.errors, status: :unprocessable_entity }
      end
    end
  end

I am getting a Errno::ENOENT no such file or directory @ rb_sysopen error.

Is this the correct way to get the tempfile path?

Also, If I use tempfile.path instead of "#{tempfile.path}", I get a nil to string error.

1

There are 1 answers

0
sgbett On BEST ANSWER

In your ensure you are using tempfile.close! this unlinks the file per https://ruby-doc.org/stdlib-2.5.3/libdoc/tempfile/rdoc/Tempfile.html#method-i-close-21

If you just use close without the bang (!) then you should be all set!