views:

160

answers:

3

I am attempting to send an email to the present borrower of a book. I've created an ActionMailer called ReturnRequestMailer which has a method called please_return.

class ReturnRequestMailer < ActionMailer::Base
  def please_return(book_loan)
    subject    'Book Return Request'
    recipients book_loan.person.email
    from       '[email protected]'
    sent_on    Time.now

    body       :book_loan => book_loan
  end
end

I am attempting to call this method from an action inside of my BooksController

def request_return
  @book = Book.find(params[:id])
  ReturnRequestMailer.please_return(@book.current_loan)
end

Which I invoke from my books index with the following link_to (ignoring for the time being that doing this in this manner probably isn't the smartest permanent solution).

<%= link_to 'Request Return', {:action => 'request_return' , :id => book} %>

Everything links up correctly but I get a NoMethodError in BooksController#request_return stating that it cannot find the method please_return for ReturnRequestMailer. What is going on that is preventing the please_return method from being visible to the BooksController?

A: 

Looking at your code it looks like the please_return method has been called as a class method, but you have defined it as an instance method. (for more detail on this see http://stackoverflow.com/questions/386115/to-use-self-or-not-in-rails/386132#386132 )

class ReturnRequestMailer < ActionMailer::Base
   def self.please_return(book_loan)
   ...

should fix it.

Note this won't actual make it send the email, but will stop the NoMethodFound error.

As nasmorn states, you need to call ReturnRequestMailer.deliver_please_return to have the mail delivered.

DanSingerman
+1  A: 

The Mailer in rails is usually used like this:

class ReturnRequestMailer < ActionMailer::Base
  def please_return(book_loan)
    subject    'Book Return Request'
    recipients book_loan.person.email
    from       '[email protected]'
    sent_on    Time.now

    body       :book_loan => book_loan
  end
end

Then in the controller out deliver_ in front of the method name and call it as a class Method:

def request_return
  @book = Book.find(params[:id])
  NewsletterMailer.deliver_please_return(@book.current_loan)
end
nasmorn
+1  A: 

add a 'deliver_' in front of your method so it will be :

def request_return
  @book = Book.find(params[:id])
  ReturnRequestMailer.deliver_please_return(@book.current_loan)
end

You don't need to define 'deliver_please_return' method, The method_missing method in ActionMailer will know to call please_return.

ez