Accessing the filename in a versioned file

In Shrine 2.8.latest, I am trying to access the filename (after upload) in order to display it on screen in the form (to show that a file has already been uploaded). The storage is using versions, and the version is named :original.

Here’s what the raw JSON looks like in my file_data column:

{"original":{"id":"21b29c3f756aca4ea8053dc16873d599.css","storage":"store","metadata":{"filename":"bootstrap.min.css","size":182898,"mime_type":"text/css"}}}

Is there a virtual attribute that I can use to access this, similar to how file_url(:original) would work?

Alternatively, and proving difficult to google for for some reason, is there a recipe to extract the original filename and stash it in a separate column in ActiveRecord during the original upload process?

Thanks,

Walter

I’ve upgraded to 3.2.latest, and added the metadata_attributes plugin to my uploader, but it doesn’t seem to be doing what it says on the tin. Perhaps this is related to versions?

  plugin :metadata_attributes, original: { filename: :name }

I originally had just filename: :name in there, but that gave me a “No method metadata on Hash” error. Adding the prefix made the error go away, but the file_name column is not being populated during upload.

Am I mis-reading how this should work?

Thanks again,

Walter

Further experimentation shows that when I remove the custom version code from my uploader, I get a working extraction. Here’s what I had previously:

# frozen_string_literal: true

require 'open3'

PandocCommandError = Class.new(StandardError)

class FileUploader < Shrine
  plugin :processing
  plugin :versions
  plugin :remove_attachment
  plugin :metadata_attributes, original: { filename: :name }

  process(:convert) do |io, context|
    doc = download_from_store(io)

    output_html = Tempfile.new(%w[pandoc .html], binmode: true)
    _stdout, stderr, status = Open3.capture3('pandoc', doc.path.to_s, '-t', 'html5', '-o', output_html.path.to_s)

    raise PandocCommandError, stderr.chomp unless status.success?

    output_html.open
    context[:record].html = output_html.read.force_encoding('UTF-8')
    output_html.rewind

    { original: io[:original], html: output_html }
  end

  process(:store) do |io, _context|
    { original: io }
  end

  private

  def download_from_store(io)
    io[:original].download
  rescue StandardError
    io.download
  end
end

And here is what worked:

class FileUploader < Shrine
  plugin :processing
  plugin :versions
  plugin :remove_attachment
  plugin :metadata_attributes, filename: :name
end

So clearly, something in that code (which was copied and pasted from a different app, which was also running 2.8, which may be a source of misunderstanding between plugins, too) was setting up the wrong value for file_data and that’s where my problem was. I’d appreciate any comments or insights you may have.

Thanks again,

Walter

It appears that, after the Shrine 3.0 upgrade, the metadata_attributes plugin isn’t working well with versions plugin anymore. The reason is that now the plugin will always try to set the metadata attribute even on promotion, not only on initial assignment, which fails because with versions the file is converted into a hash, so it’s not a Shrine::UploadedFile object anymore.

I would recommend moving to derivatives plugin, the versions plugin was clearly badly designed. There are instructions on the upgrading guide, and you can even turn on versions compatibility so that you don’t need to do any migrations (derivatives plugin stores )

Thanks very much. The derivatives plugin was in fact the key here.

Walter