簡體   English   中英

Ruby on Rails 實例與類方法

[英]Ruby on Rails instance vs class methods

我研究了 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)它被調用提供了它的一個實例方法不是一個類的方法。

要定義類方法,請在方法的定義(或類的名稱)中使用self關鍵字:

class Notifier
  def self.this_is_a_class_method
  end

  def Notifier.this_a_class_method_too
  end

  def this_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)

我和 OP 有同樣的問題,經過仔細研究,我終於弄明白了! 其他答案只是解決了何時在 Ruby 中使用實例與類方法,但是 Rails 在幕后做了一些偷偷摸摸的事情。 問題不在於何時使用類與實例方法,而是 Rails 如何允許您像調用類方法一樣調用實例方法,如上面的郵件程序示例所示。 這是由於: AbstractController::Base並且可以在這里看到: AbstractController::Base

基本上,在所有控制器(無論是您的郵件程序還是標准控制器)中,所有定義的方法都被“method_missing”攔截,然后返回該類的實例! 然后,定義的方法也被轉換為公共實例方法。 因此,因為您從不實例化這些類(例如您從不執行 Mailer.new.some_method),Rails 會自動調用method_missing並返回該 Mailer 的一個實例,然后該實例利用該類中定義的所有方法。

在您的情況下,它必須是:

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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM