Ruby on Rails实例与类方法

时间:2015-10-20 13:38:15

标签: ruby-on-rails ruby

我研究过Ruby类,实例方法和我发现的主要区别之间的主要区别是我们不需要创建该类的实例,我们可以直接在类名上直接调用该方法。

class Notifier 

def reminder_to_unconfirmed_user(user)
    headers['X-SMTPAPI'] = '{"category": "confirmation_reminder"}'
    @user = user
    mail(:to => @user["email"], :subject => "confirmation instructions reminder")
  end

end

所以,在这里我在我的reminder_to_unconfirmed_user类中定义了实例方法Notifier来向未经证实的用户发送电子邮件,当我运行Notifier.reminder_to_unconfirmed_user(User.last)时,它会被调用,前提是它是一个实例方法不是一种类方法。

3 个答案:

答案 0 :(得分:5)

要定义类方法,请在方法定义(或类名称)中使用self关键字:

class Notifier
  def self.this_method_is_a_class_method
  end

  def Notifier.this_one_is_a_class_method_too
  end

  def this_method_is_an_instance_method
  end
end

在您的情况下,reminder_to_unconfirmed_user应该被定义为类方法:

class Notifier 

  def self.reminder_to_unconfirmed_user(user)
    # ...
  end

end

然后你可以像这样使用它:

Notifier.reminder_to_unconfirmed_user(User.last)

答案 1 :(得分:1)

在你的情况下,它必须是:

class Notifier 

  def self.reminder_to_unconfirmed_user(user)
    headers['X-SMTPAPI'] = '{"category": "confirmation_reminder"}'
    @user = user
    mail(:to => @user["email"], :subject => "confirmation instructions reminder")
  end

end

顾名思义:

模型上的实例方法应该用于与模型的特定实例(调用该方法的实例)相关的逻辑/操作。

类方法适用于不在模型的单个实例上运行的事物,或者您没有可用实例的情况。在某些情况下,您确实希望对少数几组对象应用更改。 如果您想要在特定条件下更新所有用户,那么您应该选择类方法。

他们有不同的通话方式:

class Test
  def self.hi
    puts 'class method'
  end

  def hello
    puts 'instance method'
  end
end

Foo.hi # => "class method"
Foo.hello # => NoMethodError: undefined method ‘hello’ for Test:Class

Foo.new.hello # => instance method
Foo.new.hi # => NoMethodError: undefined method ‘hi’ for #<Test:0x1e871>

答案 2 :(得分:1)

我对OP做了同样的问题,在挖掘之后我终于明白了!其他答案刚刚解决了何时在Ruby中使用实例与类方法,但Rails在场景背后做了一些偷偷摸摸的事情。问题不在于何时使用类与实例方法,而是Rails如何允许您调用实例方法,就好像它是上面的邮件程序示例所示的类方法一样。原因如下:AbstractController::Base,可在此处看到:AbstractController::Base

基本上,在所有控制器中(无论它们是您的邮件程序还是标准控制器),所有已定义的方法都被“method_missing”拦截,然后返回该类的实例!然后,定义的方法也转换为公共实例方法。因此,因为你从不实例化这些类(例如你永远不会做Mailer.new.some_method),Rails会自动调用method_missing并返回该Mailer的一个实例,然后利用该类中定义的所有方法。