14
votes

I'm wondering how I could conditionally abandon sending mail within the action ActionMailer action itself.


class SomeMailer < ActionMailer::Base
  ...

  def some_emails
    some_models = Model.where(:a => 1)
    if !some_models.blank?
      mail(...)
    else
      # What to add here?
      # render :nothing => true doesn't work
    end
  end

end

Now invoking this through SomeMailer.some_emails.deliver! returns an ArgumentError: A sender (Return-Path, Sender or From) required to send a message

5
Will you be sending one email for each model, or one email with a list of all models?Samo

5 Answers

43
votes

Set perform_deliveries to false, like so:

emails = get_email_list_somehow
if emails.present?
  mail options.merge(:bcc => emails)
else
  self.message.perform_deliveries = false
end

This will quietly not try to send and should stop the error from happening.

2
votes

In Rails 3.2.9 you can finally conditionally call mail(). Here's the related GitHub thread. Now the OP's code can be reworked like this:

class SomeMailer < ActionMailer::Base
  ...

  def some_emails
    some_models = Model.where(:a => 1)
    unless some_models.blank?
      mail(...)
    end
  end

end
1
votes

The strange thing is, that with Rails 3.1.rc4 and WEBrick, it works fine on my local WEBrick webserver. But as soon as I push to Heroku cedar stack, their WEBrick throws the

ArgumentError: A sender (Return-Path, Sender or From)

You have to remove the conditional statements as stated in above answer. That fixes it so that it also works on Heroku, not just your local machine

0
votes

I had this same problem. There is no real way to do it within the ActionMailer action so I did the following in my cron task:

 users.each do |user|
  begin
    UserMailer.event_second_reminder_group_user_email(user).deliver
    puts "  - sending reminder email to user #{user.email}"
  rescue
  end
end
puts "Complete!"

Now if an error is thrown, it doesn't break the app!

-1
votes

Instead put your conditions in the place where you are making the call to SomeMailer.some_emails.deliver!