My application was sending mails in background in development but recently i installed redis and resque to use resque along with resque-mailer and now nothing is working.Everytime i get a message RuntimeError Invalid delivery method :resque.I have been trying hard to figure out whats wrong because earlier i just included resque-mailer in user_mailer.rb and thats it,my mails were running but now i dont know what wrong i did.below are my relevant file AFTER INSTALLING REDIS using Railscasts for resque.I googled alot to find but many times i came across monkey patching devise but i dont think i need to do that as my mailers were working fine without worrying about devise.Using ruby 1.9.3 and rails 3.2
im getting same error when tried with sidekiq :(
my gemfile.
gem 'resque','1.19.0' ,:require => "resque/server"
gem 'resque_mailer'
my user_mailer.rb
class UserMailer < ActionMailer::Base
include Resque::Mailer
default from: "support#mywebsite.com"
def logged_in(user.id)
Rails.logger.info 'sending mail----------registeration mail----------'
#user=User.find(user_id)
p #user
###line number 19 is below
mail(:to => #user.email, :subject => " Hi #{#user.username},You logged-in just now ")
end
app/controllers/users/devise/sessions_controller.rb
##enqueue the mailer using resque and send mail asynchronously
###this was working earlier but now its not so i made use of railscasts above to use redis
###UserMailer.logged_in(resource.id).deliver
#user_id=resource.id
Resque.enqueue(UserMailerWorker,#user_id)
now the changes that i did using Railscasts and mail is not sending giving above error
my worker
class UserMailerWorker
#queue = :user_mailer_job_queue
def self.perform(user_id)
p 'usermailer worker sending logged in mail----'
p user_id
UserMailer.logged_in(user_id).deliver
end
end
backtrace error as seen in resque-web UI---
localhost.localdomain:8119 on mailer at just now
Retry or Remove
Class
UserMailer
Arguments
"logged_in"
7
Exception
RuntimeError
Error
Invalid delivery method :resque
/usr/local/rvm/gems/ruby-1.9.3-head#latest/gems/actionmailer-3.2.0/lib/action_mailer/delivery_methods.rb:71:in `wrap_delivery_behavior'
/usr/local/rvm/gems/ruby-1.9.3-head#latest/gems/actionmailer-3.2.0/lib/action_mailer/delivery_methods.rb:83:in `wrap_delivery_behavior!'
/usr/local/rvm/gems/ruby-1.9.3-head#latest/gems/actionmailer-3.2.0/lib/action_mailer/base.rb:628:in `mail'
/mnt/hgfs/latest-master/latest/app/mailers/user_mailer.rb:19:in `logged_in'
/usr/local/rvm/gems/ruby-1.9.3-head#latest/gems/actionpack-3.2.0/lib/abstract_controller/base.rb:167:in `process_action'
/usr/local/rvm/gems/ruby-1.9.3-head#latest/gems/actionpack-3.2.0/lib/abstract_controller/base.rb:121:in `process'
/usr/local/rvm/gems/ruby-1.9.3-head#latest/gems/actionpack-3.2.0/lib/abstract_controller/rendering.rb:45:in `process'
/usr/local/rvm/gems/ruby-1.9.3-head#latest/gems/actionmailer-3.2.0/lib/action_mailer/base.rb:456:in `process'
/usr/local/rvm/gems/ruby-1.9.3-head#latest/gems/actionmailer-3.2.0/lib/action_mailer/base.rb:451:in `initialize'
/usr/local/rvm/gems/ruby-1.9.3-head#latest/gems/resque_mailer-2.2.6/lib/resque_mailer.rb:48:in `new'
/usr/local/rvm/gems/ruby-1.9.3-head#latest/gems/resque_mailer-2.2.6/lib/resque_mailer.rb:48:in `perform'
well after removing and resetting my application...i came to know why i was getting this error.its because i was not starting the resque job as well as redis.so after starting redis using redis-server and resque using bundle exec rake resque:work QUEUE='*'...my asynchronous mail started working without any problem just by including include Resque::Mailer
Related
I'm a Rails newbie, so please forgive any ignorance on my part. The issue I'm having is that I have a Resque job setup to send an email. I have the job running, but it produces an error:
Unable to deliver email [send_daily_digest_email]: wrong number of arguments (given 2, expected 0)
I get this same error when I try to test the mailer from console...
TicketMailer.send_daily_digest_email("emailaddress#domain.com").deliver_now
Here is the mailer code:
class TicketMailer < ActionMailer::Base
layout 'mailer'
include Resque::Mailer
default :from => 'test <test#ignore.com>'
def send_daily_digest_email(email)
mail(:to => email, :subject => 'test')
end
end
What am I doing wrong? Where should I look to figure this out? Thanks!
As noted in the comments, the issue was due to Rails 5 not being fully supported in the current release of the resque-mailer gem. Support is built in now, but I had to pull from master on the repo:
gem "resque_mailer", :git => "https://github.com/zapnap/resque_mailer.git"
I am getting an odd error: 'Use MyMailer.delay.mailer_action(args) to delay sending of emails.' but I can seem to find out where does it come from:
app/mailers/user_notifier.rb
class UserNotifier < ActionMailer::Base
default from: "test#testing.com"
def signup_email(user)
#user = user
mail(to: #user.email, subject: t("mailer.signup.subject"))
end
...
end
In Console, the non-delayed one works:
UserNotifier.signup_email(user).deliver
but when adding delay, error occurs:
UserNotifier.signup_email(user).delay.deliver
Rendered user_notifier/signup_email.html.erb (0.7ms)
RuntimeError: Use MyMailer.delay.mailer_action(args) to delay sending of emails.
from /Users/quindici/.rvm/gems/ruby-2.1.2/gems/delayed_job-4.0.6/lib/delayed/performable_mailer.rb:20:in `delay'
from (irb):6
from /Users/quindici/.rvm/gems/ruby-2.1.2/gems/railties-4.0.0/lib/rails/commands/console.rb:90:in `start'
from /Users/quindici/.rvm/gems/ruby-2.1.2/gems/railties-4.0.0/lib/rails/commands/console.rb:9:in `start'
from /Users/quindici/.rvm/gems/ruby-2.1.2/gems/railties-4.0.0/lib/rails/commands.rb:64:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
It used to work but was broken sometimes ago. Still didn't get my head around it. Any idea would be much appreciated! Thank you.
When you use Delayed_job you'll can access .dealy method and then you can put the action mailer method like .deliver_later to delay sending of emails.
Simply way to add delayed_job in your project:
Add in your Gemfile:
gem "delayed_job_active_record"
gem "daemons"
Create the file "config/initializers/delayed_job_config.rb" with:
Delayed::Worker.destroy_failed_jobs = false
Delayed::Worker.sleep_delay = 60
Delayed::Worker.max_attempts = 3
Delayed::Worker.max_run_time = 5.minutes
Delayed::Worker.read_ahead = 10
Delayed::Worker.default_queue_name = 'default'
Delayed::Worker.delay_jobs = !Rails.env.test?
Delayed::Worker.raise_signal_exceptions = :term
Delayed::Worker.logger = Logger.new(File.join(Rails.root, 'log', 'delayed_job.log'))
In terminal:
$ bin/rails generate delayed_job:active_record
$ bin/rake db:migrate
$ bundle
$ bin/delayed_job start
Optional to view log: tail -f log/delayed_job.log
In some Mailer in your project (You can execute this in rails console):
SomeMailer.delay.some_method
Your queue will be processed in 60 seconds. You can remove the property Delayed::Worker.sleep_delay = 60 to process immediately.
Otherwise, you can configure your application to use delayed_job like your adapter for the active jobs and process works in background. Then you need to put config.active_job.queue_adapter = :delayed_job. This mode always you send an email you don't need to use .delay, instead, you call the mailer action and .deliver_later, for example: MyMailer.your_method.deliver_later. In this mode, the active job will enqueue the email in the delayed_job.
Questions and suggestions are welcome.
Reference: https://github.com/collectiveidea/delayed_job
I think you have it backwards:
UserNotifier.signup_email(user).delay.deliver
should be
UserNotifier.delay.signup_email(user)
I have found it difficult to send exceptions of my Rails 3 app via the Airbrake gem. At first I thought there was an Airbrake configuration error on my part, but after trial and error and reading the documentation (https://github.com/thoughtbot/airbrake#readme) very closely, I found out that Airbrake does not report errors when an app is running in the development environment. It does report errors when the app is running in the production environment.
Is there a flag to generate an Airbrake configuration file that automatically includes the development environment in the list of environments in which notifications should not be sent?
Currently I am executing the command listed in the README
script/rails generate airbrake --api-key your_key_here
Straightforward.
config.consider_all_requests_local = false
instead of
config.consider_all_requests_local = true
in your config/environments/development.rb. In my case, like I suspect in many others, it was just a temporary change so I can "test" Airbrake's notify_airbrake.
You do need config.development_environments = [] in airbrake.rb
Not sure about a config options, but you can explicitly send notifications to Airbrake from a controller using
notify_airbrake(exception)
So to do this in development, you could catch all errors in your application_controller, send a notification and then handle the errors as before. Take a look at rescue_from to get started. This is how I'm doing this to get notifications from my staging environment (or, to be exact, any environment other than development and test).
class ApplicationController < ActionController::Base
rescue_from Exception, :with => :render_error
private
def render_error(exception)
render :file => "#{Rails.root}/public/500.html", :layout => false, :status => 500
logger.error(exception)
notify_airbrake(exception) unless Rails.env.development? || Rails.env.test?
end
end
I am just beginning to look into using the delayed_job gem.
To test it, I added "delayed" to the welcome email function and changed that call from
UserMailer.welcome_email(self).deliver
to
UserMailer.delay.welcome_email(self)
This is called inside the User model after_create. I see an entry show up in the delayed_job table after the function executes. Now when I run "rake jobs:work" on command line the task starts but gives errors as below
[Worker(host:Sanjay-PC pid:7008)] Starting job worker
[Worker(host:Sanjay-PC pid:7008)] Class#welcome_email failed with NoMethodError: undefined method `welcome_email' for #<Class:0x4871d60> - 0 failed attempts
[Worker(host:Sanjay-PC pid:7008)] 1 jobs processed at 0.0939 j/s, 1 failed ...
Thinking that if I changed the welcome_email method declaration to a Class method as
def self.welcome_email(user)
(added self. in front) that might help. But then when I run rake jobs:work I get the following error
rake aborted!
undefined method `welcome_email' for class `UserMailer'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/activesupport-3.0.5/lib/active_support/core_ext/module/aliasing.rb:31:in `alias_method'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/activesupport-3.0.5/lib/active_support/core_ext/module/aliasing.rb:31:in `alias_method_chain'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/delayed_job-2.1.4/lib/delayed/message_sending.rb:50:in `handle_asynchronously'
c:/mgn/mgn-r3/app/mailers/user_mailer.rb:10:in `<class:UserMailer>'
c:/mgn/mgn-r3/app/mailers/user_mailer.rb:1:in `<top (required)>'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/activesupport-3.0.5/lib/active_support/dependencies.rb:454:in `load'
<Stack truncated>
It seems to now know the class as UserMailer but it somehow doesn't see the class method welcome_email.
I am on Rails 3.0.5, Ruby 1.9.2p180 and the installed delayed_job gem is 2.1.4 - on Windows
Can't seem to find any related answers anywhere.
Thanks for your thoughts.
-S
Adding UserMailer code per #pjammer's request
class UserMailer < ActionMailer::Base
default :from => "from#example.com"
def welcome_email(user)
#user = user
#url = "http://example.com/login"
mail(:to => user.email,
:subject => "Welcome to My Awesome Site")
end
end
Just use this
UserMailer.delay.welcome_email(self).deliver
instead of
UserMailer.welcome_email(self).delay.deliver
My solution was to redefine function at the handler class (for you it's UserMailer class)
def self.taguri
'tag:ruby.yaml.org,2002:class'
end
It's a hack and I'll try to find a better solution but now it works for me.
(Rails 3.0.9, Ruby 1.9.2-p290, delayed_job 2.1.4)
https://groups.google.com/forum/?fromgroups=#!topic/delayed_job/_gvIcbXrOaE solved my handles_asynchronously error for class methods.
As per Brandon Keeper in the link above, the code is the following:
class ClassName
class << self
def foo
end
handle_asynchronously :foo
end
end
then use ClassName.delay.foo
I'm using the delayed_job gem here: https://github.com/collectiveidea/delayed_job
I have the following in an observer:
UserMailer.delay.msg_notification(record)
In user_mailer.rb
class UserMailer < ActionMailer::Base
...
def msg_notification(record)
mail(
:to => "#{record.user.email}",
:subject => "Notification"
)
end
..
end
But this errors with:
NoMethodError (undefined method `delay' for UserMailer:Class):
Any ideas? thanks
I've seen a problem like this on our Rails app (2.3.8, but the issue sounds the same). Basically, there are three ways to delay an action:
MyClass.delay.foo(arg)
Putting handle_asynchronously :foo in your class definition after the definition of foo
MyClass.send_later(:foo, arg)
For whatever reason, #3 was the only form that worked consistently across all our development machines. #1 died on our development server (Ubuntu); #2 on our designer's Mac. But #3 was fine.
Hope that helps!
Also check if you have restarted your server after the bundle install. That could be a issue too...