tamersalama
tamersalama

Reputation: 4143

Rails 3 - abandon sending mail within ActionMailer action

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

Upvotes: 16

Views: 6617

Answers (5)

Bozhidar Batsov
Bozhidar Batsov

Reputation: 56665

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

Upvotes: 3

Jack Dempsey
Jack Dempsey

Reputation: 2044

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.

Upvotes: 44

Frank
Frank

Reputation: 11

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

Upvotes: 1

doug
doug

Reputation: 2111

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!

Upvotes: 0

rohit pal
rohit pal

Reputation: 402

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

Upvotes: -1

Related Questions