Rails 4 wicked_pdf在模型中的服务器上保存pdf

我想在这样的模型中保存pdf:

def save_invoice pdf = WickedPdf.new.pdf_from_string( render_to_string(:pdf => "invoice",:template => 'documents/show.pdf.erb') ) save_path = Rails.root.join('pdfs','filename.pdf') File.open(save_path, 'wb') do |file| file << pdf end end 

保存我的Payment对象后,我在payment.rb模型中完成了。

得到一个错误:

 undefined method `render_to_string' for  

之前它在控制器中没有问题

 def show @user = @payment.user #sprawdza czy faktura nalezy do danego uzytkownika # [nie mozna podejrzec po wpisaniu id dowolnej faktury] if current_user != @user flash[:error] = I18n.t 'errors.invoice_forbidden' redirect_to '/' and return end respond_to do |format| format.html do render :layout => false end format.pdf do render :pdf => "invoice",:template => "payments/show" end end end 

我当然有一个查看payments/show.pdf.erb

Rails模型没有render_to_string方法。 渲染视图不是模型的责任。

如果您绝对需要在模型中执行此操作,则可以执行以下操作:

 def save_invoice # instantiate an ActionView object view = ActionView::Base.new(ActionController::Base.view_paths, {}) # include helpers and routes view.extend(ApplicationHelper) view.extend(Rails.application.routes.url_helpers) pdf = WickedPdf.new.pdf_from_string( view.render_to_string( :pdf => "invoice", :template => 'documents/show.pdf.erb', :locals => { '@invoice' => @invoice } ) ) save_path = Rails.root.join('pdfs','filename.pdf') File.open(save_path, 'wb') do |file| file << pdf end end 

我可能会创建一个这样的服务对象,而不是用这一切来污染我的模型:

 class InvoicePdfGenerator def initialize(invoice) @invoice = invoice @view = ActionView::Base.new(ActionController::Base.view_paths, {}) @view.extend(ApplicationHelper) @view.extend(Rails.application.routes.url_helpers) @save_path = Rails.root.join('pdfs','filename.pdf') end def save File.open(@save_path, 'wb') do |file| file << rendered_pdf end end private def rendered_pdf WickedPdf.new.pdf_from_string( rendered_view ) end def rendered_view @view.render_to_string( :pdf => "invoice", :template => 'documents/show.pdf.erb', :locals => { '@invoice' => @invoice } ) end end 

然后在模型中你可以这样做:

 def save_invoice InvoicePdfGenerator.new(self).save end 

这项工作对我来说:

 class Transparency::Report def generate(id) action_controller = ActionController::Base.new action_controller.instance_variable_set("@minisite_publication", Minisite::Publication.find(id)) pdf = WickedPdf.new.pdf_from_string( action_controller.render_to_string('minisite/publications/job.pdf.slim', layout: false) ) pdf_path = "#{Rails.root}/tmp/#{self.name}-#{DateTime.now.to_i}.pdf" pdf = File.open(pdf_path, 'wb') do |file| file << pdf end end end