Customize file name

Is there a way to set the filename to be based on a record field?
for example if the record is a user that has the field name set to ‘john’, I’d like to be able to set the filename to ‘john.jpg’

Yes, you have access to the record in Shrine#generate_location, so you can read the field, for example:

class MyUploader < Shrine
  def generate_location(io, record: nil, **)
    basename, extname = super.split(".")

    location = [basename]
    location << record.name if record.is_a?(User)
    location[-1] << extname.to_s
    location.join("/")
  end
end

Thank you for the prompt response!
Let me know if you would be open to generalizing this by extending the pretty_location plugin, as follows.

diff --git a/lib/shrine/plugins/pretty_location.rb b/lib/shrine/plugins/pretty_location.rb
index 6cc12434..f53bfdc6 100644
--- a/lib/shrine/plugins/pretty_location.rb
+++ b/lib/shrine/plugins/pretty_location.rb
@@ -17,13 +17,17 @@ def generate_location(io, **options)
         def pretty_location(io, name: nil, record: nil, version: nil, derivative: nil, identifier: nil, metadata: {}, **)
           if record
             namespace    = record_namespace(record)
             identifier ||= record_identifier(record)
           end
 
           basename = basic_location(io, metadata: metadata)
           basename = [*(version || derivative), basename].join("-")
 
+          if opts[:pretty_location][:basename] && (record_basename = record.public_send(opts[:pretty_location][:basename]))
+            basename = record_basename + '-' + basename
+          end
+
           [*namespace, *identifier, *name, basename].join("/")
         end
 
         private

Since that seems like a highly specialized use case, I don’t think it would make sense to add it to the pretty_location plugin.

However, you can call super in Shrine#generate_location to get the “pretty location”, and then make the changes you want:

class MyUploader < Shrine
  plugin :pretty_location # or load it globally in the initializer

  def generate_location(io, record: nil, **)
    location = super

    if record.is_a?(User) # or whatever condition
      location = location.sub(%r{[^/]+$}, record.name + '-\0')
    end

    location
  end
end