gpt4 book ai didi

ruby-on-rails - 在不暴露整个路径的情况下显示 Rails Carrierwave URL

转载 作者:太空宇宙 更新时间:2023-11-03 16:17:02 25 4
gpt4 key购买 nike

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


产品文件 uploader

...
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}

产品 Controller

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

问题出在下载路径上。因为我在文件 uploader 中指定了 #{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}",我会收到访问错误因为它试图上传到我电脑的根目录。 "downloads/#{model.product_id}/#{model.id}" 只是上传到名为 downloads 的 public 目录中的新文件夹,这不是我想要的做。

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


编辑:

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

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

最佳答案

找出解决方法!

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

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

这意味着在我的私有(private)文件 uploader 中我可以简单地写

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

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

但是,在我的公共(public) uploader 中,我只是......

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

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

/public/downloads/myfile.jpg

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

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

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

关于ruby-on-rails - 在不暴露整个路径的情况下显示 Rails Carrierwave URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41337412/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com