为什么我可以在 rails 中的 ActionMailer::MessageDelivery 上使用已删除的 "deliver" 方法 6
Why can I use deleted "deliver" method on ActionMailer::MessageDelivery in rails 6
irb(main)> Rails.version
=> "6.0.3.3"
irb(main)> AwesomeNotifier.send_recommend_notification(self).method(:deliver).owner
AwesomeNotifier#send_recommend_notification: processed outbound mail in 0.2ms
=> ActionMailer::MessageDelivery
irb(main)> AwesomeNotifier::MessageDelivery.instance_methods(false)
=> [:deliver_later!, :deliver_later, :deliver_now!, :deliver_now, :message, :processed?, :__setobj__, :__getobj__]
看起来 ActionMailer::MessageDelivery
中没有 deliver
方法
因为它在 5.0 commit here
上删除了
但它以某种方式起作用。
这是哪里来的deliver
??
我应该使用 deliver_later
或 deliver_now
但我想说清楚 deliver
是什么。
AwesomeNotifier::MessageDelivery
是委托对象——也就是说,它是另一个对象的包装器;虽然它提供了自己的方法,但如果您在其上调用未明确定义的方法,消息将传递给它包装的对象。
来自docs:
The ActionMailer::MessageDelivery class is used by ActionMailer::Base when creating a new mailer. MessageDelivery is a wrapper (Delegator subclass) around a lazy created Mail::Message.
虽然 MessageDelivery
定义了 deliver_later
和 deliver_now
,但调用 deliver
实际上会将调用置于 Mail::Message
的实例上。其实现是 here.
我怀疑由于历史原因委托人模式保留在这个实例上,并且可能有 Rails 代码依赖于 MessageDelivery
上可用的某些 Mail::Message
方法。但它可能会导致混淆 MessageDelivery
实际响应哪些方法以及它的预期行为可能是什么。
在您自己的代码中,如果您曾经确实需要直接访问消息,使用 MessageDelivery 的 #message
方法来显式引用可能会更清楚消息。
irb(main)> Rails.version
=> "6.0.3.3"
irb(main)> AwesomeNotifier.send_recommend_notification(self).method(:deliver).owner
AwesomeNotifier#send_recommend_notification: processed outbound mail in 0.2ms
=> ActionMailer::MessageDelivery
irb(main)> AwesomeNotifier::MessageDelivery.instance_methods(false)
=> [:deliver_later!, :deliver_later, :deliver_now!, :deliver_now, :message, :processed?, :__setobj__, :__getobj__]
看起来 ActionMailer::MessageDelivery
中没有 deliver
方法
因为它在 5.0 commit here
上删除了
但它以某种方式起作用。
这是哪里来的deliver
??
我应该使用 deliver_later
或 deliver_now
但我想说清楚 deliver
是什么。
AwesomeNotifier::MessageDelivery
是委托对象——也就是说,它是另一个对象的包装器;虽然它提供了自己的方法,但如果您在其上调用未明确定义的方法,消息将传递给它包装的对象。
来自docs:
The ActionMailer::MessageDelivery class is used by ActionMailer::Base when creating a new mailer. MessageDelivery is a wrapper (Delegator subclass) around a lazy created Mail::Message.
虽然 MessageDelivery
定义了 deliver_later
和 deliver_now
,但调用 deliver
实际上会将调用置于 Mail::Message
的实例上。其实现是 here.
我怀疑由于历史原因委托人模式保留在这个实例上,并且可能有 Rails 代码依赖于 MessageDelivery
上可用的某些 Mail::Message
方法。但它可能会导致混淆 MessageDelivery
实际响应哪些方法以及它的预期行为可能是什么。
在您自己的代码中,如果您曾经确实需要直接访问消息,使用 MessageDelivery 的 #message
方法来显式引用可能会更清楚消息。