ruby-on-rails-3 – 文件从Carrierwave文档附件链接下载

我正在尝试创建一个简单的链接,当单击时会启动与特定资源关联的文档的下载.我有一个资源模型,在该模型中有一个名为“document”的列.当单击链接时,我能够成功查看文档内联,但我更愿意下载它.我一直在阅读有关内容类型和send_file的内容,但我无法完全将它们拼凑起来以实现功能.

这是我认为我需要用于链接的代码:
<%= link_to'下载文件',:action => “download_file”%>

这会引发错误:
ResourcesController#show中的ActiveRecord :: RecordNotFound
无法找到id = download_file的资源

当我更改链接时,它会在浏览器中打开文件:
<%= link_to'打开文件',resource.document_url,:target => “_blank”%>

在我的ResourcesController中,我定义了这个方法:

def download_file
  @resource = Resource.find(params[:id])
  send_file(@resource.file.path,:filename => @resource.file.name,:type => @resource.file.content_type,:disposition => 'attachment',:url_based_filename => true)
  end

我在routes.rb中设置了一条路由,如下所示:

resources :resources do
    get 'resources',:on => :collection
  end

因此,基于此错误,似乎我在ResourcesController中的download_file方法无法确定与文档关联的资源记录的ID.

我在跑:
Rails 3.2.11
Carrierwave 0.8.0
Ruby 1.9.3-p194

我希望对此有所了解.我搜索了很多文章,但却找不到简单的教程.谢谢.

解决方法

我能够弄清楚这一点.我将尝试解释我是如何解决这个问题的.

download_file方法正确地位于ResourcesController中,但我没有使用正确的变量名.这是我的目的正确的方法定义:

def download_file
  @resource = Resource.find(params[:id])
  send_file(@resource.document.path,:type => 'application/pdf',:url_based_filename => true)
  end

在我的情况下,我在变量@resource中返回了一个记录,其中有一个与之关联的文档(同样,我使用的是Carrierwave).所以send_file需要的第一个参数是路径(参见API for send_file).此路径信息由@ resource.document.path提供.

send_file接受许多其他参数,这些参数似乎是可选的,因为我只需要其中的三个.有关其他参数,请参阅API文档.

其中一个为我抛出错误的是类型:我传递了变量“@ resource.file.content_type”,但它显然正在寻找文字.一旦我通过它application / pdf,它就有效了.如果没有明确设置,则下载的文件未添加文件扩展名.在任何情况下,对于我的应用程序,这个文档可能是各种不同的mime类型,从pdf到word到mp4.所以我不确定如何指定多个.

对于我的目的(下载而不是在浏览器中显示),真正重要的论点是:需要设置为’attachment’而不是’inline’的disposition.

另一个参数:url_based_filename显然用于从URL确定文件的名称.由于我没有提供文件名,也许这是我提供给正在下载的文件的唯一方法,但我不确定.

我还需要将link_to标记更改为:
<%= link_to'下载文件',:action => ‘download_file’,:id => resource.id%>

请注意,提供具有当前资源的id的:id符号提供了识别相关资源所需的特定信息.

我希望这可以帮助其他人.这对其他人来说一定非常明显,因为我没有找到任何关于文件下载文件的基本教程.我还在学习很多东西.

更新:我不得不玩这个来获得理想的行为.以下是正在运行的新方法:

def download_file
        @resource = Resource.find(params[:id])
        send_file(@resource.document.path,:url_based_filename => false)
      end

通过这些更改,我不再需要设置:type.设置“:url_based_filename => true”保持在URL中的记录ID之后命名文件.基于我对该参数的函数的读取,将此设置为false似乎是违反直觉的,但是,这样做会产生在实际文件名之后命名文件的期望结果.

我还使用了mime-types gem并将以下内容添加到我的video_uploader.rb文件中:

require 'carrierwave/processing/mime_types'

class VideoUploader < CarrierWave::Uploader::Base
include CarrierWave::MimeTypes
process :set_content_type

这个gem显然设置了文件名中文件扩展名猜出的mime类型.这样做使得我不必在我的download_file方法中的send_file参数中设置:显式类型.

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...