Rails 中的 PDF 发票和 Mailer

Pdf invoice and Mailer in Rails

我尝试学习 Rails 但我被卡住了。 我有用户、工作、发票和客户模型。我正在使用 Prawn 创建发票和 Pdf 发票。 Pdf 发票未保存(我不想保存 pdf,只是为了在浏览器中查看 pdf),现在我想要一个按钮通过电子邮件发送 pdf 发票。我在发票显示视图​​中有 2 个按钮,一个用于查看 Pdf,另一个用于通过电子邮件发送 pdf。

= link_to 'View PDF', invoice_path(@invoice, format: "pdf")
\|
= link_to "Send Email", invoice_mail_path(current_user, @invoice), class: "btn btn-xs btn-primary"

我有:

invoice_mailer.rb

default from: "example@yahoo.com"

  def invoice_mail(invoice, user, job)
    @invoice = invoice
    @user = user
    @job = job
    attachments["#{(@invoice.invoice_number)}.pdf"] = InvoicePdf.new(@invoice, view_context).render

    mail(to: 'example@yahoo.com',
         subject: "A new invoice from xxx")
  end

invoices_controller.rb

def invoice_mail

# @invoice = Invoice.last
@invoice = Invoice.new(@invoice)
@user = current_user
@job = current_user.jobs

InvoiceMailer.invoice_mail(@invoice, @user, @job).deliver_now

flash[:notice] = "Invoice has been sent."
redirect_to invoices_path 
end

routes.rb

get :invoice_mail, to: 'invoices#invoice_mail', as: :invoice_mail

In invoices_controller in def invoice_mail 如果我有

@invoice = Invoice.last

正在工作,正在发送附有 pdf 的电子邮件,但正在获取最后一张发票。如果我有

@invoice = Invoice.new(@invoice)

给我错误。

除了@invoice = Invoice.last,我需要什么来获取当前发票?还是我哪里做错了?

当我点击终端上的发送电子邮件按钮时:

Started GET "/invoice_mail.16-446cd684-c756-4ea3-a820-17756f44098d" for 127.0.0.1 at 2019-03-22 11:07:30 -0400
Processing by InvoicesController#invoice_mail as 
User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" =  ORDER BY "users"."id" ASC LIMIT   [["id", 2], ["LIMIT", 1]]
↳ /Users/ovi_tsb/.rvm/gems/ruby-2.4.1/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
Completed 404 Not Found in 2ms (ActiveRecord: 0.4ms)



ActiveRecord::RecordNotFound (Couldn't find Invoice without an ID):

app/controllers/invoices_controller.rb:124:in `invoice_mail'
@invoice = Invoice.new(@invoice)

这在您的控制器中毫无意义。您正在为 @invoice 分配一个 nil 值给 Invoice.new(@invoice) 的值,这等同于 Invoice.new(nil)。那不应该引发任何错误,但这样做确实没有意义。

据推测,您想做的是根据 ID 查找发票。就像:

@invoice = Invoice.find(params[:id])

这意味着您的请求应包含一个 :id 参数。如果没有,则需要将其包括在内。但我相信这应该有它:

= link_to "Send Email", invoice_mail_path(current_user, @invoice), 
                        class: "btn btn-xs btn-primary"

其次,上面的link_to不需要包含current_usercurrent_user 是对 Rails 通过用户会话抓取的 User 的引用。换句话说,它默认存在于您的控制器中。所以不要费心通过它:

= link_to "Send Email", invoice_mail_path(@invoice), 
                         class: "btn btn-xs btn-primary"

让我们用这个新信息清理您的控制器:

def invoice_mail
  @invoice = Invoice.find(params[:id]) # :id should be the invoice ID
  @jobs = current_user.jobs

  InvoiceMailer.invoice_mail(@invoice, current_user, @jobs).deliver_now
  flash[:notice] = "Invoice has been sent."
  redirect_to invoices_path 
end