下载Rails资产 - 开发中的文件路径与生产 [英] Downloading Rails Assets - File-paths In Development vs Production

查看:195
本文介绍了下载Rails资产 - 开发中的文件路径与生产的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 downloads_controller.rb 与一个下载动作,我想触发一个文件的下载它住在名为下载的文件夹中,该文件夹位于我添加到资产路径中的名为 download_assets 的文件夹中。 / p>

   -  download_assets [添加到资产路径] 
- 下载
- file_1.pdf
- file_2.pdf
...

我可以使用以下方式成功访问该文件夹中的任何文件:



http:/ /my-app.dev/assets/downloads/file.pdf



为了使用send_file,我需要文件系统路径文件而不是URL。我可以使用 Rails.root 获取Rails项目根目录的路径,使用 asset_path(path)。但是,问题是因为我正在开发中,所以在这个路径上没有文件。该文件存储在:

  path / to / rails / project / app / assets / download_assets / downloads / file.pdf 

操作:

 code> def下载
@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
如果Rails.env ==开发|| 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 创建一个名为 config.yml 的文件*设置如下:



config.yml:

  --- 
##不是制表符。 3个空格。 (如果这会影响你)
开发:
path_to_uploads:/ path / to / downloads / for / development

生产:
path_to_uploads:/ path / to /下载/ for / production

测试:
path_to_uploads:/ path / to / downloads / for / test

然后在同一个目录( / config / initializers / )中创建一个名为 config.rb



config.rb:

 code> APP_CONFIG = YAML.load_file(#{Rails.root} /config/initializers/config.yml)

转到你的控制器:



foo_controller.rb:

  class FooController< ApplicationController 
def下载
#...
path_to_uploads = Rails.root.to_s + APP_CONFIG [#{Rails.env}] ['path_to_uploads']
## By将其传递给Rails.env对象,它将返回当前环境并处理为您选择正确的环境。
end
end

有一个优秀的RailsCast使用YAML找到环境 here。








*请注意,文件名是任意的。


I have a downloads_controller.rb with a single download action which I want to trigger the download of a file that lives in a folder called downloads which lives in a folder called download_assets which I have added to my asset paths.

- download_assets [Added to asset paths]
   - downloads
      - file_1.pdf
      - file_2.pdf
      ...

I can successfully access any files in the folder using:

http://my-app.dev/assets/downloads/file.pdf

In order to use send_file I need the file system path to this file rather than the URL. I can get the path the the root of my Rails project using Rails.root, and the path to the file using asset_path(path). However, the problem is that because I'm in development, there is no file at this path. The file is stored in:

path/to/rails/project/app/assets/download_assets/downloads/file.pdf

The action:

   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

To get this to work in development I need to use the following:

"#{Rails.root}/app/assets/download_assets/#{file_path}"

However this will fail in Production because assets will be precompiled and moved into assets.

My current workaround is:

   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

Is there an alternative to supplying a different path based on environment as this seems fragile?

解决方案

In short:

Yes.

In long:

in /config/initializers create a file called config.yml* Set it up like so:

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

Then create a file in the same directory (/config/initializers/) called config.rb

config.rb:

APP_CONFIG = YAML.load_file("#{Rails.root}/config/initializers/config.yml")

Hop over to your controller:

foo_controller.rb:

      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

There is an excellent RailsCast on using YAML to find the environment here.

Hope that helps!


*Please note that the filenames are arbitrary.

这篇关于下载Rails资产 - 开发中的文件路径与生产的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆