Show Rails Carrierwave URL without exposing entire path

折月煮酒 提交于 2019-12-06 04:43:53

Found out how to solve this!

In each uploader, there is a special method called root that we can use to set the unseen filepath. First, I made a special uploader base class called PublicUploader.

class PublicUploader < CarrierWave::Uploader::Base
  def root
    "${Rails.root}/public"
  end
end

Then, I set the global CarrierWave root to the Rails.root.

CarrierWave.configure do |config|
  # These permissions will make dir and files available only to the user running
  # the servers
  config.permissions = 0600
  config.directory_permissions = 0700
  config.storage = :file

  # This avoids uploaded files from saving to public/ and so
  # they will not be available for public (non-authenticated) downloading
  config.root = Rails.root
end

This means in my private file uploader I can simply write

def store_dir
  "downloads/#{model.product_id}/#{model.id}"
end

and it will save in "#{Rails.root}/downloads/..." as opposed to "#{Rails.root}/public/downloads/...". This means I can use a controller to limit access.

However, in my public uploader, I simply had...

def store_dir
  "public/downloads/#{model.product_id}/#{model.id}"
end

...because I wanted to save in my "#{Rails.root}/public" folder. However, this meant that rails would show a url like the following

/public/downloads/myfile.jpg

This poses a problem, as Rails omits the public from the path. So the above would 404. However when the uploader inherits from the special class where I define the root, then I can simply say

def store_dir
  "downloads/#{model.product_id}/#{model.id}"
end

It will upload and show the image correctly! Hope this can help someone.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!