ruby-on-rails Rails在后台导出csv

w8f9ii69  于 2023-03-24  发布在  Ruby
关注(0)|答案(2)|浏览(129)

我做了一个CSV导入器和导出器在铁路的文章模型.它需要的文章,并在CSV格式下载它.它工作正常,但我希望它是在一个backgrond过程.有人能告诉如何执行导入和导出在后台.
这是我用过的文件-

Article_controller

  def index
    @articles = Article.all
    @articles = Article.includes(:user)
    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @articles }
      format.atom
      @articles = Article.order(:name).page params[:page]
      format.csv { send_data @articles.to_csv, filename: "#{current_user.email}-#{Date.today}.csv" }

    end
  end
...
article.rb

def self.import(file,userid)
      user = User.find_by(id: userid)
      if user
        CSV.foreach(file.path, headers: true) do |row|
        user.articles.create! row.to_hash
        end
      end
    end
  def self.to_csv
    attributes = %w{id title content}
    CSV.generate(headers: true) do |csv|
      csv << attributes
      all.each do |article|
        csv << article.attributes.values_at(*attributes)
      end
    end
  end
piok6c0g

piok6c0g1#

导入:

导入更容易,因为用户不必在导入完成后接收反馈。
正如在评论中提到的,你可以使用ActiveJobsidekiq这样的后端:
你可以在你的文章中使用后台工作。rb:

def self.import(file, userid)
  CSVImportJob.perform_later(file.path, userid)
end

class CSVImportJob 
  def perform(filepath, userid)
    user = User.find_by(id: userid)
    if user
      CSV.foreach(filepath, headers: true) do |row|
        user.articles.create! row.to_hash
      end
    end
  end
end

导出:

导出比较棘手,因为您不能从后台作业向用户发送文件。
后台处理与导入类似:

def self.export
  CSVExportJob.perform_later
end

class CSVExportJob 
  def perform
    attributes = %w{id title content}
    CSV.generate(headers: true) do |csv|
      csv << attributes
      Article.find_each do |article|
        csv << article.attributes.values_at(*attributes)
      end
    end
    # Save CSV somewhere and notify its readiness
  end
end

然后你必须创建一个不同的路由来触发CSV的创建。ArticleController#index将总是返回最后导出的CSV,它保存在DB或文件系统中的某个地方。

ovfsdjhp

ovfsdjhp2#

要扩展导出,请务必使用job或Sidekiq worker来生成CSV。
要通知用户作业/员工何时完成,请使用hotwire/turbo广播更新和/或发送电子邮件。
当涉及到交付在作业/工人中生成的csv时,ActiveStorage使其非常容易:

class User < ApplicationRecord
  has_one_attached :download, dependent: :delete_all
end

然后像这样将csv字符串附加到模型:

class GenerateCsvJob < ApplicationJob
  queue_as :default

  def perform(user_id)
    user = User.find(user_id)
    csv_string = ::CSV.generate do |csv| etc...
    user.download.attach(io: StringIO.new(csv_string), filename: "file.csv",content_type: "application/csv")
  end
end

并像这样链接到下载:

<%= link_to "Download", rails_blob_path(@user.download, disposition: :attachment), target: "_blank" %>

相关问题