How to get full file path?

1,488 views
Skip to first unread message

radovan...@gmail.com

unread,
Oct 3, 2017, 1:23:17 PM10/3/17
to Shrine
Hello,

i migrating from Carrierwave to Shrine as lightweighting from heavy tight on Rails.
I have central media storage, every file (image, document, video, audio) is stored in one place (model, db, and file system) and then file is associated to another objects.

I don't find any way how to get full file path. 

Carrierwave by calling
file.path
returns full path as
/Users/Rado/Development/my_app/public/uploads/asset/filename.jpg

but in Shrine it returns only partial path with calling "url" method, because path is not implemented
/asset/filename.jpg
i could append another partial from storage, but can't get full path.

is there any way how to find full path?

my config and files looks like this:
require 'shrine'
require 'shrine/storage/file_system'
require 'media_info'


Shrine.storages = {
  cache
: Shrine::Storage::FileSystem.new('public', prefix: 'uploads/cache'),
  store
: Shrine::Storage::FileSystem.new('public', prefix: 'uploads/asset')
}


Shrine.plugin :activerecord
Shrine.plugin :cached_attachment_data # for forms


class FileUploader < Shrine
  plugin
:keep_files
  plugin
:pretty_location
  plugin
:determine_mime_type,
         analyzer
: ->(io, analyzers) do
           
MediaInfo.parse(io.path)&.general&.internet_media_type
         
end


 
def generate_location(io, context)
   
if context[:record]
      id
= context[:record].id if context[:record].respond_to?(:id)
   
end


    basename
= File.basename(context.fetch(:action) == :cache ? super : context.metadata.fetch('filename'))
    basename
= "#{context[:version]}-#{basename}" if context[:version]


   
['asset', id, basename].compact.join('/')
 
end
end



Janko Marohnić

unread,
Oct 3, 2017, 3:20:09 PM10/3/17
to radovan...@gmail.com, Shrine
The concept of a "full path" is specific to the filesystem storage, that's why Shrine::UploadedFile doesn't implement a #path method. If you look at the Shrine::Storage::FileSystem docs, you'll see that the storage object provides a #path method. So if you have a Shrine::UploadedFile object, you can retrieve its full path by passing in the #id to FileSystem#path:

  uploaded_file.storage.path(uploaded_file.id)

As a reminder, a Shrine::UploadedFile object is what is returned by model's attachment method, so if you have a Photo model with an "image" attachment, this would be how you would retrieve the full path to the :original version:

  photo.image[:original].storage.path(photo.image[:original].id)

Kind regards,
Janko

--
You received this message because you are subscribed to the Google Groups "Shrine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-shrine+unsubscribe@googlegroups.com.
To post to this group, send email to ruby-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ruby-shrine/c7f5fa0b-e901-4a47-9b6f-199eaadd2572%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Message has been deleted
Message has been deleted

radovan...@gmail.com

unread,
Oct 4, 2017, 5:02:02 PM10/4/17
to Shrine
Thanks for hint. 
If i understand right for File storage Shrine doesn't inherit from Rubys File class, but implements own right?

Then when i want to get full path to file i need to use something like this in model class:
def original_path
  
Rails.root.join(file.storage.path(file.id))
end

Thanks for hint me!

Regards,
Radovan
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-shrine...@googlegroups.com.

Janko Marohnić

unread,
Oct 5, 2017, 2:30:32 PM10/5/17
to Radovan Šmitala, Shrine
If i understand right for File storage Shrine doesn't inherit from Rubys File class, but implements own right?

Yes, the CarrierWave uploader doesn't inherit from `File` class either, it just implements #path explicitly. It wouldn't make sense to inherit from `File` class, because neither CarrierWave uploader nor Shrine::UploadedFile represent a file on the filesystem (at least not generally).

Then when i want to get full path to file i need to use something like this in model class:
 
def original_path
  Rails.root.join(file.storage.path(file.id))
end

Yes, that's correct. My bad, I forgot the Rails.root.join part. Alternatively you can use Rails.root.join to construct the directory name on Shrine::Storage::FileSystem initialization:

  Shrine.storages = {
    cache: Shrine::Storage::FileSystem.new(Rails.root.join('public'), prefix: 'uploads/cache'),
    store: Shrine::Storage::FileSystem.new(Rails.root.join('public'), prefix: 'uploads/asset')
  }

Then you can omit it in the model:

  def original_path
    file.storage.path(file.id)
  end

Note that this won't be necessary as of Shrine 2.8.0, as the filesystem storage will automatically expand the directory path on initialization.

Kind regards,
Janko

To unsubscribe from this group and stop receiving emails from it, send an email to ruby-shrine+unsubscribe@googlegroups.com.

To post to this group, send email to ruby-...@googlegroups.com.

radovan...@gmail.com

unread,
Oct 9, 2017, 12:27:47 PM10/9/17
to Shrine
It works like a charm. Thank you.

You said Shrine 2.8.0 creates expand file path to full-path.
Does it means this will be breaking change for path in id attribute?

Janko Marohnić

unread,
Oct 9, 2017, 12:36:17 PM10/9/17
to Radovan Šmitala, Shrine
Does it means this will be breaking change for path in id attribute?

No, the Shrine::UploadedFile#id will remain unchanged, the path expanding will only affect the FileSystem storage itself. To be specific, the only change is that now the Shrine::Storage::FileSystem#path and Shrine::Storage::FileSystem#directory methods will return the full path, even when the given directory path was relative.

Kind regards,
Janko

To unsubscribe from this group and stop receiving emails from it, send an email to ruby-shrine+unsubscribe@googlegroups.com.

To post to this group, send email to ruby-...@googlegroups.com.

radovan...@gmail.com

unread,
Oct 9, 2017, 12:38:40 PM10/9/17
to Shrine
Good news :) Thank for response.

Have a nice day!
Reply all
Reply to author
Forward
0 new messages