I try to learn Rails and I'm stuck. I have User, Job, Invoice and Customer models. I'm creating an invoice and Pdf invoice with Prawn. The Pdf invoice is not saved(I don't want to save pdf's, just to see the pdf in browser) and now I want a button to send pdf invoice by email. I have in invoice show view 2 buttons one for view Pdf and another send pdf by email.
= 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"
I have:
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 if I have
@invoice = Invoice.last
is working and is sending the email with pdf attached but is grabbing the last invoice. If I have
@invoice = Invoice.new(@invoice)
is give me error.
What do I need instead of @invoice = Invoice.last to grab the current invoice ? Or what I did wrong ?
When i hit send email button I have on terminal :
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" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["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)
This, in your controller, makes no sense. You're assigning a @invoice
a nil value to the value of Invoice.new(@invoice)
, which is the equivalent of Invoice.new(nil)
. That shouldn't throw any errors, but it really doesn't make sense to do.
Presumably, what you want to do is find an invoice based on ID. Just like:
@invoice = Invoice.find(params[:id])
That means your request should include an :id
parameter. If it does not, you need to include it. But I believe this should have it:
= link_to "Send Email", invoice_mail_path(current_user, @invoice),
class: "btn btn-xs btn-primary"
Secondly, the link_to
above need not include a current_user
. current_user
is a reference to the User
grabbed by Rails via the user's session. In other words, it'll exist in your controller by default. So don't bother passing it:
= link_to "Send Email", invoice_mail_path(@invoice),
class: "btn btn-xs btn-primary"
Lets clean up your controller with this new information:
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