Ruby on rails 下载Rails资产-开发与生产中的文件路径
我有一个Ruby on rails 下载Rails资产-开发与生产中的文件路径,ruby-on-rails,ruby,controller,download,sendfile,Ruby On Rails,Ruby,Controller,Download,Sendfile,我有一个downloads\u controller.rb和一个download操作,我想触发下载一个文件,该文件位于名为downloads的文件夹中,该文件夹位于我添加到资产路径中的名为download\u assets的文件夹中 - download_assets [Added to asset paths] - downloads - file_1.pdf - file_2.pdf ... 我可以使用以下方法成功访问文件夹中的任何文件: 为了使
downloads\u controller.rb
和一个download
操作,我想触发下载一个文件,该文件位于名为downloads
的文件夹中,该文件夹位于我添加到资产路径中的名为download\u assets
的文件夹中
- download_assets [Added to asset paths]
- downloads
- file_1.pdf
- file_2.pdf
...
我可以使用以下方法成功访问文件夹中的任何文件:
为了使用send_file,我需要该文件的文件系统路径,而不是URL。我可以使用Rails.root
获取Rails项目的根路径,使用asset\u path(path)
获取文件的路径。然而,问题是因为我正在开发中,所以在这个路径上没有文件。该文件存储在:
path/to/rails/project/app/assets/download_assets/downloads/file.pdf
行动:
def download
@download = Download.find(params[:id])
file_path = "downloads/#{@download.filename}.pdf"
file_path = "#{Rails.root}#{ActionController::Base.helpers.asset_path(file_path)}"
send_file(file_path, :type=>"application/pdf", x_sendfile: true)
end
要使其在开发中发挥作用,我需要使用以下方法:
"#{Rails.root}/app/assets/download_assets/#{file_path}"
但是,这将在生产中失败,因为资产将被预编译并移动到资产中
我目前的解决办法是:
file_path = "downloads/#{@download.filename}.pdf"
if Rails.env == "development" || Rails.env == "test"
file_path = "#{Rails.root}/app/assets/download_assets/#{file_path}"
else
file_path = "#{Rails.root}{ActionController::Base.helpers.asset_path(file_path)}"
end
是否有其他方法可以根据环境提供不同的路径,因为这似乎很脆弱?是的
在/config/initializers
中创建一个名为say“config.yml
”的文件,如下所示进行设置:
config.yml:
---
## NOT a tab character. 3 spaces. (In case that affects you)
development:
path_to_uploads: /path/to/downloads/for/development
production:
path_to_uploads: /path/to/downloads/for/production
test:
path_to_uploads: /path/to/downloads/for/test
APP_CONFIG = YAML.load_file("#{Rails.root}/config/initializers/config.yml")
class FooController < ApplicationController
def download
# ...
path_to_uploads = Rails.root.to_s + APP_CONFIG["#{Rails.env}"]['path_to_uploads']
## By handing it the Rails.env object, it will return the current environment and handle selecting the correct environment for you.
end
end
然后在同一目录(/config/initializers/
)中创建一个名为config.rb
config.rb:
---
## NOT a tab character. 3 spaces. (In case that affects you)
development:
path_to_uploads: /path/to/downloads/for/development
production:
path_to_uploads: /path/to/downloads/for/production
test:
path_to_uploads: /path/to/downloads/for/test
APP_CONFIG = YAML.load_file("#{Rails.root}/config/initializers/config.yml")
class FooController < ApplicationController
def download
# ...
path_to_uploads = Rails.root.to_s + APP_CONFIG["#{Rails.env}"]['path_to_uploads']
## By handing it the Rails.env object, it will return the current environment and handle selecting the correct environment for you.
end
end
跳到您的控制器:
foo\u controller.rb:
---
## NOT a tab character. 3 spaces. (In case that affects you)
development:
path_to_uploads: /path/to/downloads/for/development
production:
path_to_uploads: /path/to/downloads/for/production
test:
path_to_uploads: /path/to/downloads/for/test
APP_CONFIG = YAML.load_file("#{Rails.root}/config/initializers/config.yml")
class FooController < ApplicationController
def download
# ...
path_to_uploads = Rails.root.to_s + APP_CONFIG["#{Rails.env}"]['path_to_uploads']
## By handing it the Rails.env object, it will return the current environment and handle selecting the correct environment for you.
end
end
class FooController
在使用YAML查找环境方面有一个很好的RailsCast
希望有帮助