在Ruby中调用类的实例方法的原因?

时间:2018-04-27 10:12:43

标签: ruby-on-rails ruby ruby-on-rails-4

我想知道是否有任何具体原因可以做到这一点,或者这是某人犯下的愚蠢错误(或者是我不理解的其他事情)。

class SomeMailer < ActionMailer::Base
  def first_method(user)
    mail(to: user.email, subject: "Testing")
  end
end

此方法在代码中的其他位置调用,如下所示

SomeMailer.first_method(user).deliver

3 个答案:

答案 0 :(得分:3)

ActionMailer::Base类很奇怪......是的,你确实在类上调用了实例方法 - 这显然不适用于'普通'类!

但是some meta-programming magic under the hood

module ActionMailer
  class Base < AbstractController::Base
    def method_missing(method_name, *args) # :nodoc:
      if action_methods.include?(method_name.to_s)
        MessageDelivery.new(self, method_name, *args)
      else
        super
      end
    end
  end
end

如果你仔细查看the rails documentation,你会发现在类上调用实例方法对于邮件程序来说是很正常的事情。

答案 1 :(得分:1)

这就是rails的工作方式。 在导轨指南中也提到了

  

您永远不会实例化您的邮件程序类。相反,您只需调用您在类本身上定义的方法。

Rails通过调用04-27 13:05:48.838 27993-27993/com.phomotech.dicegame I/Ads: Updating ad debug logging enablement. 04-27 13:05:48.880 27993-27993/com.phomotech.dicegame I/Ads: Starting ad request. 04-27 13:05:48.882 27993-27993/com.phomotech.dicegame I/Ads: Use AdRequest.Builder.addTestDevice("B445576D53CC2D3C563D556644F72240") to get test ads on this device. 04-27 13:05:48.908 27993-27993/com.phomotech.dicegame D/DynamitePackage: Instantiating com.google.android.gms.ads.ChimeraMobileAdsSettingManagerCreatorImpl 04-27 13:05:48.917 27993-27993/com.phomotech.dicegame I/Ads: Updating ad debug logging enablement. 04-27 13:05:48.921 27993-27993/com.phomotech.dicegame I/Ads: Starting ad request. 04-27 13:05:48.922 27993-27993/com.phomotech.dicegame I/Ads: Use AdRequest.Builder.addTestDevice("B445576D53CC2D3C563D556644F72240") to get test ads on this device. 04-27 13:05:48.953 27993-29240/com.phomotech.dicegame W/Ads: Update ad debug logging enablement as false 04-27 13:05:48.953 27993-29213/com.phomotech.dicegame W/Ads: Update ad debug logging enablement as false 04-27 13:05:49.691 27993-28016/com.phomotech.dicegame I/Ads: No fill from ad server. 04-27 13:05:49.819 27993-27993/com.phomotech.dicegame W/Ads: Failed to load ad: 3 04-27 13:05:50.096 27993-27993/com.phomotech.dicegame I/Ads: Scheduling ad refresh 70000 milliseconds from now. 04-27 13:05:50.133 27993-27993/com.phomotech.dicegame I/Ads: Ad finished loading. 来执行内部处理。 基本上,邮件程序类中定义的任何操作方法都将被method_missing拦截,并将返回MessageDelivery的实例,否则它将运行默认实现。行动方法来自何处? ActionMailer :: Base继承自AbstractController :: Base,因此它与控制器完全相同 - 它返回给定类的一组公共实例方法。

Rails本身鼓励这种行为。有关详细信息,请参阅此link

答案 2 :(得分:0)

我会尝试回答这个问题,因为我在处理现有代码时遇到了类似的情况。

当您对某个类执行回调时,类中的实例方法会有所帮助。例如,如果要对从该类创建的对象执行某些操作。

假设您有另一个班级用户,并且您希望在创建新用户后立即向用户发送电子邮件。在这种情况下,您可以通过执行

在该对象上调用此方法

after_save :method_name