显示 Rails 载波 URL 而不暴露整个路径
Show Rails Carrierwave URL without exposing entire path
我正在制作一个付费下载的网络应用程序,我遵循了 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}
,所以文件保存在 public 文件夹外部的一个名为 downloads
的文件夹中。然而,这有一个意想不到的副作用。当我从我的模型中检索 URL 时,我得到了整个绝对路径,而不是相对于 Rails 根目录的路径。
例如,ProductFile.first.file.url
returns "/home/doomy/Documents/resamplr/downloads/3/1/aaaa.zip"
,当它应该只是 return /downloads/3/1/aaa.zip
.
此行为似乎与 ProductFileUploader
中指定的内容有关。
例如,如果我将 store_dir
更改为 "/downloads/#{model.product_id}/#{model.id}"
,我会收到一个访问错误,因为它正在尝试上传到我的 PC 的根目录。 "downloads/#{model.product_id}/#{model.id}"
只是上传到 public
目录中名为 downloads 的新文件夹,这不是我想要做的。
关于如何进行的任何建议?谢谢。
编辑:
我发现将 Carrierwave 配置文件中的 config.root
设置为 Rails.root
可以实现此行为。如果我这样做,在我的 ProductFileUploader
中我可以将 store_dir
指定为 "downloads/#{model.product_id}/#{model.id}
.
但是,这意味着 public 文件保存为“/public/...”link。 Rails 自动丢弃 public 文件夹名称并使用 URL.
中的子目录名称
找到解决方法了!
在每个上传器中,都有一个名为root
的特殊方法,我们可以使用它来设置看不见的文件路径。首先,我制作了一个名为 PublicUploader 的特殊上传器库 class。
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/..."
。这意味着我可以使用控制器来限制访问。
然而,在我的 public 上传器中,我只是......
def store_dir
"public/downloads/#{model.product_id}/#{model.id}"
end
...因为我想保存在我的 "#{Rails.root}/public"
文件夹中。但是,这意味着 rails 会显示如下 url
/public/downloads/myfile.jpg
这带来了一个问题,因为 Rails 从路径中省略了 public
。所以上面会是 404。然而,当上传者从我定义 root
的特殊 class 继承时,我可以简单地说
def store_dir
"downloads/#{model.product_id}/#{model.id}"
end
它将正确上传并显示图像!希望这可以帮助某人。
我正在制作一个付费下载的网络应用程序,我遵循了 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}
,所以文件保存在 public 文件夹外部的一个名为 downloads
的文件夹中。然而,这有一个意想不到的副作用。当我从我的模型中检索 URL 时,我得到了整个绝对路径,而不是相对于 Rails 根目录的路径。
例如,ProductFile.first.file.url
returns "/home/doomy/Documents/resamplr/downloads/3/1/aaaa.zip"
,当它应该只是 return /downloads/3/1/aaa.zip
.
此行为似乎与 ProductFileUploader
中指定的内容有关。
例如,如果我将 store_dir
更改为 "/downloads/#{model.product_id}/#{model.id}"
,我会收到一个访问错误,因为它正在尝试上传到我的 PC 的根目录。 "downloads/#{model.product_id}/#{model.id}"
只是上传到 public
目录中名为 downloads 的新文件夹,这不是我想要做的。
关于如何进行的任何建议?谢谢。
编辑:
我发现将 Carrierwave 配置文件中的 config.root
设置为 Rails.root
可以实现此行为。如果我这样做,在我的 ProductFileUploader
中我可以将 store_dir
指定为 "downloads/#{model.product_id}/#{model.id}
.
但是,这意味着 public 文件保存为“/public/...”link。 Rails 自动丢弃 public 文件夹名称并使用 URL.
中的子目录名称找到解决方法了!
在每个上传器中,都有一个名为root
的特殊方法,我们可以使用它来设置看不见的文件路径。首先,我制作了一个名为 PublicUploader 的特殊上传器库 class。
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/..."
。这意味着我可以使用控制器来限制访问。
然而,在我的 public 上传器中,我只是......
def store_dir
"public/downloads/#{model.product_id}/#{model.id}"
end
...因为我想保存在我的 "#{Rails.root}/public"
文件夹中。但是,这意味着 rails 会显示如下 url
/public/downloads/myfile.jpg
这带来了一个问题,因为 Rails 从路径中省略了 public
。所以上面会是 404。然而,当上传者从我定义 root
的特殊 class 继承时,我可以简单地说
def store_dir
"downloads/#{model.product_id}/#{model.id}"
end
它将正确上传并显示图像!希望这可以帮助某人。