我正在处理我的第一个应用程序,我需要一些帮助,允许我的用户下载包含页面上显示的某些变量的文本文件。
以购物清单为例。
假设您允许用户创建产品购物清单,然后在购物清单页面上显示带有商品的购物清单,
例如。本地主机:3000 /列表/我的列表
看看下面的示例代码(可能不正确):
File.open('shopping_list.txt', 'w') do |file|
file.puts 'Item 1: #{product_1.name}'
file.puts 'Item 2: #{product_2.name}'
file.puts 'Item 3: #{product_3.name}'
end
然后创建具有以下内容的文本文件:
Item 1: Eggs
Item 2: Butter
Item 3: Bread
然后,用户应该可以通过下载链接下载此文件(我不希望该文件存储在服务器上)。
我不知道如何实现这一点,但我希望你们能指导我。 :d
的 TL; DR
答案 0 :(得分:7)
我假设有一个List
资源,其中属性name
作为列表名称,列表has_many
项目具有属性description
首先,创建下载路径以更改路由config/routes.rb
resources :lists do
member {get "download"}
end
现在,如果您在控制台中运行rake routes
,您应该会看到类似
/lists/:id/download
你现在应该有更多帮手download_list_url
& download_list_path
在您的视图中使用
<ul>
<% @lists.each do |list| %>
<li> <%= list.name %> - <%= link_to 'Download List', download_list_path(list) %> </li>
<% end %>
</ul>
在lists_controller
中添加操作,并且实际上并不想将文件保留在服务器磁盘上,只是将数据作为字符串流式传输
def download
list = List.find(params[:id])
send_data list.as_file,
:filename => "#{list.name}.txt",
:type => "text/plain"
end
最后你看到我使用了as_file
方法你应该添加到模型中(我不喜欢在控制器,胖模型,瘦控制器中做这些东西)。所以在List
模型中
def as_file
output = [self.name]
self.items.each {|item| output << item.description }
output.join("\n")
end
答案 1 :(得分:3)
您说您不想将文件存储在服务器上,而是根据请求“下载”该文件;这听起来像您只想生成并传送文本文档以响应下载链接。有几种方法,但您希望确保设置mime类型,以便浏览器将其视为文本文件而不是html文档。
product_info = [
"Item 1: #{product_1.name}",
"Item 2: #{product_2.name}",
"Item 3: #{product_3.name}",
].join("\n")
render :text => product_info # implies :content_type => Mime::Type["text/plain"]
顺便说一下,上面打开/置位的例子不会输出您的想法,因为单引号字符串不会插入。
答案 2 :(得分:3)
所以,你希望:
create text files populated with model data (perhaps create a method
to achieve this?)
text files should not be stored on the server, but
created as users click the download button (not sure if this is the
rails way but perhaps someone could show me a better way)
你有正确的想法,这是做什么的:
在模型中创建一个方法以生成文本文件内容。假设此方法称为list_data
您似乎有一个名为my_list
的现有控制器操作。因此我们可以在控制器中调用我们的新方法,如下所示:
def my_list
# pre-existing code
respond_to do |format|
format.html # show html page as before
format.text do
send_data @list.list_data, :content_type => 'text/plain', :filename => 'my-shopping-list.txt'
end
end
end
要链接到下载,只需使用link_to :action => my_list, :format => 'text'
有关send_data
答案 3 :(得分:1)
您可以尝试TempFile和send_file的组合。在你的控制器动作..
file = Tempfile.new('foo')
file.write("hello world")
file.close
send_file file.path
答案 4 :(得分:0)
在Rails 2.3中,您可以使用Template Streaming。使用Redmine我可以记住这样的事情,你必须适应你的情况。参考:Streaming and file downloads
require "prawn"
class ClientsController < ApplicationController
# Generate a PDF document with information on the client and return it.
# The user will get the PDF as a file download.
def download_pdf
client = Client.find(params[:id])
send_data(generate_pdf, :filename => "#{client.name}.pdf", :type => "application/pdf")
end
private
def generate_pdf(client)
Prawn::Document.new do
text client.name, :align => :center
text "Address: #{client.address}"
text "Email: #{client.email}"
end.render
end
end
使用Thong Kuah你必须改变“content_type”参数:
def my_list
# pre-existing code
respond_to do |format|
format.html # show html page as before
format.text do
send_data @list.list_data, :content_type => 'text/plain', :filename => 'my-shopping-list.txt'
end
end
end