这部分主要讲述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中有代码实例

results matching ""

    No results matching ""