这部分主要讲述upload和download的知识
1.通过既有的项目生成在线的pdf并且下载
#添加gem
gem 'prawn'
#设置routes.rb
get 'clients/:id/download_pdf', to: "clients#download_pdf", as: :pdf
#clients_controller.rb
def download_pdf
client = Client.find(params[:id])
send_data generate_pdf(client), filename: "#{client.name}.pdf", type: "application/pdf"
end
private
def generate_pdf(client)
Prawn::Document.new do
#建立字体
font_families["msyh"] = {
#字体从mac的字体软件中寻找,并且放置在桌面上
:normal => { :file => "/Users/jayzen/Desktop/Fangsong.ttf" }
}
#使用已经创建好的字体进行显示
font("msyh") do
text client.name, align: :center
text "Address: #{client.address}"
text ":Email: #{client.email}"
end
end.render
end
#通过下面的url获得pdf文件
clients/1/download_pdf #获得pdf文件
?.通过rails原生代码上传pdf文件
#支架
rails g scaffold tag name
#model中设置虚拟属性
class Tag < ActiveRecord
attr_accessor :attachment
end
#controller中设置attachment白名单
params.require(:tag).permit(:name, :attachment)
#controller中添加upload方法
class TagsController < ApplicationController
def create
@tag = Tag.new(tag_params)
if @tag.save
upload
......
end
private
def upload
....
end
end
#重点定义upload方法
def upload
uploaded_io = params[:tag][:attachment]
#注意必须新增文件夹,然后才能在该文件夹下面生成文件
demo = Dir.mkdir(File.join(Rails.root, 'public', 'uploads', "#{@tag.id}"))
File.open(Rails.root.join('public','uploads', "#{@tag.id}", uploaded_io.original_filename), 'wb') do |file|
file.write(uploaded_io.read)
end
end
?.删除和更新附件
class TagsController < ApplicationController
before_action :set_tag, only: [:show, :edit, :update, :destroy]
def index
@tags = Tag.all
end
def show
end
def new
@tag = Tag.new
end
def edit
end
def create
@tag = Tag.new(tag_params)
if @tag.save
file_upload
redirect_to @tag
else
render :new
end
end
def update
if @tag.update(tag_params)
unless params[:tag][:attachment].nil? #更新过程中,附件默认为空
file_delete
file_upload
end
redirect_to @tag
else
render 'edit'
end
end
def destroy
@tag.destroy
file_delete
redirect_to tags_url, notice: 'has been deleted!'
end
private
def set_tag
@tag = Tag.find(params[:id])
end
def tag_params
params.require(:tag).permit(:name, :attachment)
end
def file_upload
if params[:tag][:attachment]
uploaded_io = params[:tag][:attachment]
demo = Dir.mkdir(File.join(Rails.root, 'public', 'uploads', "#{@tag.id}"))
File.open(Rails.root.join('public','uploads', "#{@tag.id}", uploaded_io.original_filename), 'wb') do |file|
file.write(uploaded_io.read)
end
end
end
def file_delete
path = "#{Rails.root}/public/uploads/#{@tag.id}"
if Dir.exist?(path)
unless Dir.empty?(path)
Dir.entries(path).select{|x| x =~ /[^.]/}.each do |file|
File.delete("#{path}/#{file}")
Dir.delete(path)
end
else
Dir.delete(path)
end
end
end
end
?.把磁盘中已经存在文件发送给客户端
#其他辅助代码如上所示
#routes.rb
get 'tags/:id/download_pdf', to: "tags#download_pdf"
#controller.rb
def download_pdf
@tag = Tag.find(params[:id])
path = "#{Rails.root}/public/uploads/#{@tag.id}"
file = Dir.entries(path).last
send_file("#{path}/#{file}",
filename: "#{@tag.name}.pdf",
type: "application/pdf")
end
?通过model中的回调方法删除文件
#赋值代码如前所示
class Tag < ApplicationRecord
attr_accessor :attachment
after_destroy_commit :delete_disk_file
private
def delete_disk_file
path = "#{Rails.root}/public/uploads/#{self.id}"
if Dir.exist?(path)
unless Dir.empty?(path)
Dir.entries(path).select{|x| x =~ /[^.]/}.each do |file|
File.delete("#{path}/#{file}")
Dir.delete(path)
end
else
Dir.delete(path)
end
end
end
end
#修改controller代码
去掉file_upload
?.实时流:ActionController::Live
模块可以和浏览器建立持久连接,随时随地把数据传送给浏览器
#rails g controller welcome index
#设置root
root 'welcome#index'
#welcome_controller.rb
class WelcomeController < ApplicationController
include ActionController::Live
def index
response.headers['Content-Type'] = 'text/event-stream'
100.times {
response.stream.write "hello world\n"
sleep 1
}
ensure
response.stream.close
end
end
#应用举例
在线歌词,guides中有代码实例