2010-11-08 83 views
19

我有一个Rails 3应用程序在Heroku上使用Devise。问题是我正在用Sendgrid发送电子邮件,并且电子邮件传送速度很慢,它会使应用程序挂起。所以我有兴趣使用delayed_job在后台对邮件进行排队,以便我的应用程序能够响应用户。Rails + Devise + delayed_job?

Devise如何与delayed_job一起使用?任何方式来设置Devise使用delayed_job?

回答

24

罗伯特五月作品:https://gist.github.com/659514

config/initializers目录添加到文件:

module Devise 
    module Models 
    module Confirmable 
     handle_asynchronously :send_confirmation_instructions 
    end 

    module Recoverable 
     handle_asynchronously :send_reset_password_instructions 
    end 

    module Lockable 
     handle_asynchronously :send_unlock_instructions 
    end 
    end 
end 
+3

将该代码添加到'config/initializers'目录中的某个file.rb中。 – Zabba 2011-03-15 08:16:32

+0

这对我来说不起作用,也许是因为如果使用可能使用的Rails 3邮件程序,则不支持此方法。请参阅此链接以获取更多信息:https://github.com/collectiveidea/delayed_job并转至Rails 3 Mailers部分 – sq1020 2013-03-31 23:18:56

0

不确定为什么您需要验证任何delayed_job任务。只需让设计认证的控制器操作将电子邮件传递排队到库方法即可。

1

我不确定Devise提供了一种简单的方法来完成电子邮件传送的背景。然而,有些方法可以通过DelayedJoy做到这一点。 DelyedJob提供了一个“handle_asynchronously”功能,如果注入DeviseMailer可以确保交付发生在后台。

在你的配置试试这个/ application.rb中

config.after_initialize do 
    ::DeviseMailer.handle_asynchronously :deliver_confirmation_instructions 
    # or 
    ::DeviseMailer.handle_asynchronously :deliver! 
end 

您需要与实验。你也可以尝试继承DeviseMailer,并将其设置为在config/initializer/devise_mailer_setup.rb中的初始化程序中异步传递,或者为此设置。

-4

我一般认为最好避免任何和所有后台作业任务管理器可用于Ruby和Rails的时期。他们吮吸。

相反,我使用crontab这是一个古老的程序,非常擅长工作。每隔一段时间做一个脚本来完成你的肮脏工作,并告诉crontab在正确的时间使用rails runner运行它。这将让那些烦人的长时间运行的任务超出Rails应用程序其余部分的运行时间,但如果您需要它,仍可访问数据库和整个Rails堆栈。

+5

我的要求,“任何和所有后台作业任务管理器”吸不同意。 Ruby Toolbox在Ruby的排队选项上有一个很好的比较:http://ruby-toolbox.com/categories/queueing.html – 2011-01-03 01:24:17

+2

所以说你有一个导入,将新产品或新产品的信息放入你的应用程序。现在,新产品需要生成一些元数据或者没有。你打算为产品表添加一个标志,以便你的cronjob可以选择这些项目吗?你多久运行一次cronjob?每十分钟?如果一次执行运行时间超过10分钟,该怎么办?你将有竞争的进程在运行。看起来更像是你试图用crontab破解的东西最终会变成一个穷人 - 实现一个工作队列。更好地使用不会影响数据库架构和模型的专用队列。 – 2011-11-30 16:18:37

0

我使用delayed_job_mailer插件在Rails 2应用程序中完成此操作。不知道是否使用Rails 3

6

我发现没有上述工作对我来说。我正在使用Devise 2.0.4和Rails 3.2.2 with delayed_job_active_record 0.3.2

devise实际上谈论在代码的注释中做这样的事情的方式是覆盖User类中的方法。因此,我解决它像这样,它完美的作品:

应用程序/模型/ User.rb

def send_on_create_confirmation_instructions 
    Devise::Mailer.delay.confirmation_instructions(self) 
end 
def send_reset_password_instructions 
    Devise::Mailer.delay.reset_password_instructions(self) 
end 
def send_unlock_instructions 
    Devise::Mailer.delay.unlock_instructions(self) 
end 
+0

覆盖这些方法破坏其他功能......它似乎工作,但未设置reset_password_token on用户模型请参阅我的解决方案 – fringd 2012-05-15 20:17:34

+2

如果您查看最新Devise中的send_reset_password_instructions代码: #重置重置密码令牌并通过电子邮件发送重置密码指令 def send_reset_password_instructions generate_reset_password_token!如果should_generate_reset_token? self.devise_mailer.reset_password_instructions(self).deliver end 上面的建议会导致密码令牌不会生成。 – justingordon 2012-05-28 10:39:50

3

这是为我工作的事情:

在app /模型/用户

.RB

# after your devise declarations 
    handle_asynchronously :send_reset_password_instructions 
    handle_asynchronously :send_confirmation_instructions 
    handle_asynchronously :send_on_create_confirmation_instructions 

你可能并不需要所有的人,这取决于设计的模块要包括

+0

适用于Rails 3.2.16和Devise 3.2.3。我也使用devise_invitable 1.3.4,为此我添加了'handle_asynchronously:deliver_invitation'。 – 2014-04-11 22:57:49

+0

好吧,我评论得太快了。我的用户模型中也覆盖了'send_reset_password_instructions'。它在异步运行时无法正常工作。 ZachBeta [2014年1月6日对Github的评论](https://github.com/scambra/devise_invitable/issues/58)让我尝试了'handle_asynchronously:send_devise_notification',它似乎处理包括邀请在内的所有事情。 Devise源代码在延迟排队时也有[冗长的评论](https://github.com/plataformatec/devise/blob/3d9dea39b2978e3168604ccda956fb6ec17c5e27/lib/devise/models/authenticatable.rb#L129-L174)。 – 2014-04-12 02:46:10

+0

如何为“devise_token_auth”创业板做到这一点? – vipin8169 2016-03-28 08:07:18

0

对于delayed_job_active_record设计,只需使用以下内容。 (它添加到user.rb model

handle_asynchronously :send_devise_notification, :queue => 'devise'