响应_TO和服务对象



我当前正在使用docx_replace Gem将数据插入到一组文档中。宝石非常简单。基本上,它以您的导轨控制器的特殊方法运行(引用文档):

def user_report
  @user = User.find(params[:user_id])
  respond_to do |format|
    format.docx do
      # Initialize DocxReplace with your template
      doc = DocxReplace::Doc.new("#{Rails.root}/lib/docx_templates/my_template.docx", "#{Rails.root}/tmp")
      # Replace some variables. $var$ convention is used here, but not required.
      doc.replace("$first_name$", @user.first_name)
      doc.replace("$last_name$", @user.last_name)
      doc.replace("$user_bio$", @user.bio)
      # Write the document back to a temporary file
      tmp_file = Tempfile.new('word_tempate', "#{Rails.root}/tmp")
      doc.commit(tmp_file.path)
      # Respond to the request by sending the temp file
      send_file tmp_file.path, filename: "user_#{@user.id}_report.docx", disposition: 'attachment'
    end
  end
end

但是,这使我的控制器肿了,所以我试图将其放入这样的对象(继续使用上面的示例):

class UserReportService
    def initialize(user)
        @user=user
    end
    def user_report_generate
        respond_to do |format|
            format.docx do
                # Initialize DocxReplace with your template
                doc = DocxReplace::Doc.new("#{Rails.root}/lib/docx_templates/my_template.docx", "#{Rails.root}/tmp")
                # Replace some variables. $var$ convention is used here, but not required.
                doc.replace("$first_name$", @user.first_name)
                doc.replace("$last_name$", @user.last_name)
                doc.replace("$user_bio$", @user.bio)
                # Write the document back to a temporary file
                tmp_file = Tempfile.new('word_tempate', "#{Rails.root}/tmp")
                doc.commit(tmp_file.path)
                # Respond to the request by sending the temp file
                send_file tmp_file.path, filename: "user_#{@user.id}_report.docx", disposition: 'attachment'
            end
        end
    end
end

并在我的控制器中完成了以下内容:

def user_report
  UserReportService.new(@user).user_report_generate
end

但是,当我调用控制器方法时,我会收到以下错误:

17:58:10 web.1  | NoMethodError (undefined method `respond_to' for #<UserReportService:0x000000041e5ab0>):
17:58:10 web.1  |   app/services/user_report_service.rb:17:in `user_report_generate'
17:58:10 web.1  |   app/controllers/user_controller.rb:77:in `user_report'

我阅读了words_to,如果我正确理解文档,则是控制器特定的方法(这可以解释问题)。我如何能够解决这个问题?

respond_tosend_file应该保留在您的控制器中,但其余逻辑可以移至服务对象中。

首先,让服务对象返回temp_file:

class UserReportService
  def initialize(user)
    @user=user
  end
  def user_report_generate
    # Initialize DocxReplace with your template
    doc = DocxReplace::Doc.new("#{Rails.root}/lib/docx_templates/my_template.docx", "#{Rails.root}/tmp")
    # Replace some variables. $var$ convention is used here, but not required.
    doc.replace("$first_name$", @user.first_name)
    doc.replace("$last_name$", @user.last_name)
    doc.replace("$user_bio$", @user.bio)
    # Write the document back to a temporary file
    tmp_file = Tempfile.new('word_tempate', "#{Rails.root}/tmp")
    doc.commit(tmp_file.path)
    # Return the tmp_file
    tmp_file
  end
end

实例化服务对象,检索临时文件,然后将其发送给用户:

def user_report
  respond_to do |format|
    format.docx do
      tmp_file = UserReportService.new(@user).user_report_generate
      send_file tmp_file.path, filename: "user_#{@user.id}_report.docx", disposition: 'attachment'
    end
  end
end

最新更新