【问题标题】:Show Rails Carrierwave URL without exposing entire path显示 Rails Carrierwave URL 而不暴露整个路径
【发布时间】:2016-12-27 08:32:13
【问题描述】:

我正在制作一个付费下载的网络应用程序,我按照 Carrierwave 的protecting uploads 指南进行操作。一切都按预期工作,除了一件事。这是我当前的设置:


产品文件上传器

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

路线

  get "/downloads/:product_id/:product_file_id/:filename", :controller => "products", action: "download", conditions: {method: :get}

ProductsController

def download
  product_file = ProductFile.find(params[:product_file_id])
  name = File.basename(product_file.file.file.file)
  send_file "#{Rails.root}/downloads/#{product_file.product.id}/#{product_file.id}/#{name}", :x_sendfile => true
end

问题在于下载路径。因为我在文件上传器中指定了#{Rails.root},所以文件保存在公用文件夹外部名为downloads 的文件夹中。然而,这有一个意想不到的副作用。当我从我的模型中检索 URL 时,我得到了整个绝对路径,而不是相对于 Rails 根目录的路径。

例如,ProductFile.first.file.url 返回 "/home/doomy/Documents/resamplr/downloads/3/1/aaaa.zip",而它应该只返回 /downloads/3/1/aaa.zip

此行为似乎与ProductFileUploader 中指定的内容有关。

例如,如果我将 store_dir 更改为 "/downloads/#{model.product_id}/#{model.id}",我会在尝试上传到我的 PC 的根目录时收到访问错误。 "downloads/#{model.product_id}/#{model.id}" 只是上传到 public 目录中的一个新文件夹,名为 downloads,这不是我想做的。

关于如何进行的任何建议?谢谢。


编辑:

我发现将载波配置文件中的config.root 设置为Rails.root 允许这种行为。如果我这样做,在我的ProductFileUploader 中,我可以将store_dir 指定为"downloads/#{model.product_id}/#{model.id}

但是,这意味着公共文件使用“/public/...”链接保存。 Rails 会自动丢弃公用文件夹名称,并在 URL 中使用子目录名称。

【问题讨论】:

    标签: ruby-on-rails ruby carrierwave


    【解决方案1】:

    了解如何解决这个问题!

    在每个上传器中,都有一个名为root 的特殊方法,我们可以使用它来设置看不见的文件路径。首先,我创建了一个名为 PublicUploader 的特殊上传器基类。

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

    然后,我将全局 CarrierWave 根设置为 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
    

    这意味着在我的私人文件上传器中我可以简单地写

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

    它会保存在"#{Rails.root}/downloads/..." 而不是"#{Rails.root}/public/downloads/..."。这意味着我可以使用控制器来限制访问。

    但是,在我的公共上传器中,我只是...

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

    ...因为我想保存在我的"#{Rails.root}/public" 文件夹中。但是,这意味着 rails 会显示如下所示的 url

    /public/downloads/myfile.jpg

    这带来了一个问题,因为 Rails 从路径中省略了 public。所以上面会是404。但是当上传者继承自我定义root的特殊类时,我可以简单地说

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

    它将正确上传并显示图像!希望这可以帮助某人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-01
      • 2016-01-02
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      • 2015-08-08
      • 1970-01-01
      相关资源
      最近更新 更多