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

编程入门 行业动态 更新时间:2024-10-27 16:30:04
本文介绍了在不暴露整个路径的情况下显示Rails Carrierwave URL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在制作带有付费下载的Web应用程序,并且遵循了Carrierwave的保护上传。一切都按预期进行,可以节省一件事。这是我当前的设置:

I'm making a webapp with paid downloads, and I followed Carrierwave's guide for protecting uploads. Everything is working as expecting save one thing. Here's my current setup:

产品文件上传器

... 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根的路径。

The problem is with the download path. Because I specified #{Rails.root} in the File Uploader, the file saves in a folder external from the public folder called downloads. This has an unintended side effect, however. When I retrieve the URL from my model, I get the entire absolute path, not the path relative to the Rails Root.

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

So for instance, ProductFile.first.file.url returns "/home/doomy/Documents/resamplr/downloads/3/1/aaaa.zip", when it should instead just return /downloads/3/1/aaa.zip.

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

This behaviour seems to be attached to what is specified in the ProductFileUploader.

例如,如果我将 store_dir 更改为 / downloads /#{model.product_id} / #{model.id} ,由于它试图上传到PC的根目录时出现访问错误。 downloads /#{model.product_id} /#{model.id} 只需上传到公开称为下载的目录,这不是我想要的。

For instance, if I change the store_dir to "/downloads/#{model.product_id}/#{model.id}", I get an access error as it is trying to upload to the root of my PC. "downloads/#{model.product_id}/#{model.id}" simply uploads to a new folder in the public directory called downloads, which is not what I want to do.

有关如何进行操作的任何建议?谢谢。

Any advice on how to proceed? Thanks.

编辑:

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

I have found that setting the config.root in a Carrierwave config file to the Rails.root allows for this behavior. If I do this, in my ProductFileUploader I can specify the store_dir as "downloads/#{model.product_id}/#{model.id}.

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

However, this means public files are saved with a "/public/..." link. Rails automatically discards the public foldername and uses subdirectory names in the URL.

推荐答案

找出了解决方法!

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

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

然后,我将全局CarrierWave根目录设置为Rails.root。

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

,它将保存为#{Rails.root} / downloads /...\"反对#{Rails.root} / public / downloads /...\"。这意味着我可以使用控制器来限制访问。

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

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

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

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

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.

更多推荐

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

本文发布于:2023-11-23 09:15:39,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1620904.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:路径   情况下   Rails   Carrierwave   URL

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!