我正在使用Caracal Gem导出Docx文件,gem正常生成文档。但是,当我尝试打印合同数据时,出现错误。这可能是一些路由问题,我被困在这两个星期中,几乎要放弃了。 错误是找不到与ID =相反的操作记录 这是我的代码,我突出显示了代码中的各个部分。 Routes.rb
Rails.application.routes.draw do
get 'grayscale/index'
get 'contratos/page' HERE IS THE ROUTING
devise_for :users, path: '', path_names: {sign_in: 'login', sign_out: 'logout', sign_up: 'registrar'}
resources :contratos
root 'contratos#index'
get '/contrato_export' => 'contratos#export'
resources :contratos do
member do
# /contratos/:id/export
get 'export'
end
end
end
contratos_controller.rb
before_action :authenticate_user!
before_action :set_contrato, only: [:show, :edit, :update, :destroy, :export]
access all: [:show, :index], user: {except: [:destroy, :new, :create, :update, :edit]}, site_admin: :all
require './lib/generate_pdf'
def page
contrato = Contrato.find(params[:id])<---HERE IS THE PROBLEM!!!!!
Caracal::Document.save(Rails.root.join("public", "example.docx")) do |docx|
docx.style do
id 'Body'
name 'body'
font 'Times New Roman'
size 24
end
docx.h2 'Contrato'
docx.p do
style 'Body'
text 'Lorem ipsun dolor sit amet'
text contrato.day <--- HERE IS THE DATA THAT I WANT TO PRINT IN THE DOCX. (IN THE CONTRATO SHOW is @contrato.day, I WANT THAT DATE TO BE PRINTED.
end
end
path = File.join(Rails.root, "public")
send_file(File.join(path, "example.docx"))
end
答案 0 :(得分:1)
该教程简直是垃圾。只需使用ActionController::MimeResponds,您就可以完全完全(或至少我认为您尝试做的)REST相同的事情,而无需添加任何其他路由:
class ContratosController < ApplicationController
# GET /contratos/1
# GET /contratos/1.pdf
# GET /contratos/1.docx
def show
respond_to do |format|
format.html {}
format.pdf { send_file Contratos::PdfConverter.call(@contrato) }
format.docx { send_file Contratos::XMLConverter.call(@contrato) }
end
end
end
这里的关键是使您的控制器保持瘦身。众所周知,控制器很难测试。
我们实际上尚未声明Contratos::PdfConverter
,但这是您可以使用service object pattern的地方:
# app/services/base_service.rb
class BaseService
def self.call(*args, **kwargs, &block)
new(*args, kwargs, &block)
end
end
# app/services/contratos/docx_converter.rb
module Contratos
class DocxConverter < BaseService
# @return [Pathname]
def call(contrato)
path = Rails.root.join("public", "example.docx")
Caracal::Document.save(path) do |docx|
docx.style do
id 'Body'
name 'body'
font 'Times New Roman'
size 24
end
docx.h2 'Contrato'
docx.p do
style 'Body'
text 'Lorem ipsun dolor sit amet'
text contrato.day # ...
end
end
path
end
end
end
# app/services/contratos/pdf_converter.rb
module Contratos
class PdfConverter < BaseService
def call(contrato)
# generate PDF here
end
end
end
这使您可以分别测试转换,避免将控制器变成燃烧的垃圾堆。
答案 1 :(得分:1)
您缺少params
get 'contratos/:id/page', to: 'contratos#page'
#or
resources :contratos do
member do
get 'export' # /contratos/:id/export
get 'page' # add this!
end
end