我有一个rails应用程序,我们也在添加邮件列表功能。我试图整合两个宝石,ahoy_email(0.3.0)和mailkick(0.1.4),并遇到SystemStackError: stack level too deep
错误。
邮件代码很简单:
class AdminMailer < ApplicationMailer
# ...
def generated_recommendations(recommendations)
@recommendations = recommendations
mail(subject: "Recommendations generated for #{Date.today.strftime("%Y-%m-%d")}")
end
end
在崩溃之前,堆栈跟踪如下所示:
--> #0 Mailkick::Mailer.mail(headers#Hash, &block#NilClass) at /home/mike/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/mailkick-0.1.4/lib/mailkick/mailer.rb:4
#1 AhoyEmail::Mailer.mail_with_ahoy(headers#Hash, &block#NilClass) at /home/mike/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/ahoy_email-0.3.0/lib/ahoy_email/mailer.rb:27
#2 Mailkick::Mailer.mail(headers#Hash, &block#NilClass) at /home/mike/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/mailkick-0.1.4/lib/mailkick/mailer.rb:4
#3 AhoyEmail::Mailer.mail_with_ahoy(headers#Hash, &block#NilClass) at /home/mike/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/ahoy_email-0.3.0/lib/ahoy_email/mailer.rb:27
#4 Mailkick::Mailer.mail(headers#Hash, &block#NilClass) at /home/mike/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/mailkick-0.1.4/lib/mailkick/mailer.rb:4
看起来每个gem在另一个中调用mail
方法(或者由于alias_method_chain调用而在AhoyEmail中调用mail_with_ahoy
,见下文)。我用byebug和相关的Mailkick代码跟踪它(见***行)
module Mailkick
module Mailer
def mail(headers = {}, &block)
message = super # *** This ends up calling AhoyEmail::Mailer.mail_with_ahoy
Mailkick::Processor.new(message).process
message
end
end
end
和相关的AhoyEmail代码是(见***)
module AhoyEmail
module Mailer
def self.included(base)
base.extend ClassMethods
base.class_eval do
# ...
alias_method_chain :mail, :ahoy
end
end
module ClassMethods
# ...
def mail_with_ahoy(headers = {}, &block)
# this mimics what original method does
return message if @_mail_was_called && headers.blank? && !block
message = mail_without_ahoy(headers, &block) # *** This calls Mailkick::Mailer.mail
AhoyEmail::Processor.new(message, self).process
message
end
end
end
两个宝石的功能略有不同,在AhoyEmail的情况下是通过:
ActionMailer::Base.send :include, AhoyEmail::Mailer
在Mailkick的案例中,它是通过:
ActionMailer::Base.send(:prepend, Mailkick::Mailer)
对我来说,看起来宝石只是冲突(因为他们都在改变ActionMailer::Base.mail
并不能很好地发挥作用)并且我没有看到明显的解决方法。自从Mailkick在Ahoy电子邮件的自述文件中被引用后,我感到很惊讶,所以我想我可能会遗漏一些明显的东西。任何帮助非常感谢!
答案 0 :(得分:0)
事实证明我使用的ahoy_email
gem(来自RubyGems)的版本已经在github上更新以解决此问题。解决方案是将Gemfile中的相应行更新为:
gem 'ahoy_email', github: 'ankane/ahoy_email'
请参阅github上的相关问题: https://github.com/ankane/ahoy_email/issues/61
解析此问题的ahoy_email
gem中的差异在于:
https://github.com/ankane/ahoy_email/commit/9416ab989b942cd556d09380f9072c260c2d6551
alias_method_chain
的使用已经消失,取而代之的是Module#prepend,它解决了问题。仔细观察一下,我发现在Rails 5中将弃用alias_method_chain
(请参阅https://github.com/rails/rails/pull/19434)。
编辑2016-05-12:此修补程序发布了新版本(0.3.1)的gem,所以现在我已将我的Gemfile更新为:
gem 'ahoy_email', '>= 0.3.1'