title: Downloading Rails Assets - File-paths In Development vs Production
body: <p>I have a <code>downloads_controller.rb</code> with a single <code>download</code> action which I want to trigger the download of a file that lives in a folder called <code>downloads</code> which lives in a folder called <code>download_assets</code> which I have added to my asset paths.</p>
  
  <pre><code>- download_assets [Added to asset paths]
     - downloads
        - file_1.pdf
        - file_2.pdf
        ...
  </code></pre>
  
  <p>I can successfully access any files in the folder using:</p>
  
  <p><strike><a href="http://my-app.dev/assets/downloads/file.pdf" rel="nofollow">http://my-app.dev/assets/downloads/file.pdf</a></strike></p>
  
  <p>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 <code>Rails.root</code>, and the path to the file using <code>asset_path(path)</code>. However, the problem is that because I'm in development, there is no file at this path. The file is stored in:</p>
  
  <pre><code>path/to/rails/project/app/assets/download_assets/downloads/file.pdf
  </code></pre>
  
  <p>The action:</p>
  
  <pre><code>   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=&gt;"application/pdf", x_sendfile: true)
     end
  </code></pre>
  
  <p>To get this to work in development I need to use the following:</p>
  
  <pre><code>"#{Rails.root}/app/assets/download_assets/#{file_path}"
  </code></pre>
  
  <p>However this will fail in Production because assets will be precompiled and moved into <code>assets</code>.</p>
  
  <p>My current workaround is:</p>
  
  <pre><code>   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
  </code></pre>
  
  <p><strong>Is there an alternative to supplying a different path based on environment as this seems fragile?</strong></p>