使用这个railscast http://railscasts.com/episodes/127-rake-in-background?autoplay=true 作为示例/灵感(即我不是在尝试实现rails转换代码,只是将其用作灵感(,我试图将由user.rb模型中的after_create回调触发的邮件程序移动到一个耙子任务中,这样它就可以在后台运行。在我将其移动到耙子任务之前,邮件程序正在工作,但它不再工作了。
我没有从 User.rb 模型调用邮件程序,这是它最初设置的方式(请参阅 user.rb 中注释掉的代码(,而是调用 rake 任务,然后调用 UserMailer.welcome_email 方法。
在原始代码中,"self"作为参数提交(来自User.rb(到user_mailer.rb中welcome_email(user)
的方法。在我试图把它变成一个耙子任务时,我给USER_INSTANCE分配了"self",它应该在mailer.rake中作为ENV["USER_INSTANCE"]拾取。 这也是railscast建议的。
在途中的某个地方它不起作用。 有什么想法吗?
用户.rb
after_create :send_welcome_email
def send_welcome_email
system "rake :send_mailing USER_INSTANCE=self &" #note the & forks the task
#UserMailer.welcome_email(self).deliver <-- how it was originally.
end
mailer.rake
desc "Send mailing"
task :send_mailing => :environment do
UserMailer.welcome_email(ENV["USER_INSTANCE"]).deliver #moved from user.rb to here but now with environment variable instead of parameter
end
不变 User_mailer.rb
class UserMailer < ActionMailer::Base
default :from => "blahblah@gmail.com"
def welcome_email(user)
mail(:to => user.email, :subject => "Invitation Request Received")
end
结束
目前您正在执行此操作
system "rake :send_mailing USER_INSTANCE=self &"
这与转到命令行并键入相同
rake :send_mailing USER_INSTANCE=self &
self只是一个字面上的字符串,我认为你想做的是这个
system "rake :send_mailing USER_INSTANCE=#{self} &"
但这最终相当于在命令行上运行它
rake :send_mailing USER_INSTANCE=<User::xxxxx>
rake 不会将其序列化到您的用户活动记录对象中;当您使用系统时,与调用代码无关
另一种选择 - 您的 Rake 任务可以采用整数 - user_id,然后通过 User.find 访问记录但是随着after_create将在事务中运行,它会变得更加复杂,因此一旦您的 Rake 任务运行,它可能会也可能不会完成该事务
我建议不要尝试重新发明一种在rails中进行后台处理的方法,已经有很好的尝试和真正的解决方案可用
有关某些选项,请参阅 http://railscasts.com/?tag_id=32