找不到ActionRecord。找不到ID =

时间:2020-02-26 17:28:28

标签: ruby-on-rails ruby

我正在使用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

2 个答案:

答案 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