2009-08-28 29 views
51

宣佈Ruby的方法調用我剛開始學習Ruby on Rails的,我也遇到過類似的代碼如下:類身體

class Post < ActiveRecord::Base 
validates_presence_of :title 
belongs_to :user 
end 

有兩種方法的類體內調用。 我很難找到任何紅寶石文檔, 描述瞭如何從一個類的主體(但不包括任何方法)調用方法調用。 我擁有的所有書籍僅描述如何定義類和實例方法以及如何從其他方法中調用它們。

我的問題是:如何 和當這些方法叫什麼名字? 他們是如何定義的?它們是否在一些活動記錄模塊中定義了mixin?

回答

3

你所看到的是一個ActiveRecord對象一流水平的方法。爲了編寫你自己的方法,你可以將它們寫成插件,然後通過重新打開類定義將它們包含到ActiveRecord中。 on Rails的Ruby的指導創建一個插件:

http://guides.rubyonrails.org/plugins.html

佔地面積怎麼一會寫這樣的插件/類級別的方法。它是一個關於如何圍繞這些方法的意義以及它們如何與實例進行交互的頭腦的好文檔。

+1

一顆寶石也適用。 – 2009-08-28 05:03:46

11

回覆:如何以及何時這些方法叫什麼名字?

[被加載的類時,他們被稱爲。你可以把一個斷點的方法之一,看到它被稱爲你的Rails項目啓動的一部分。]

他們是如何定義的?

[他們是一流的方法。由於這是紅寶石,他們可以通過多種方式來定義。]

他們是在一些活動記錄模塊定義混入?

[在這種情況下,

validates_presence_of在 供應商/軌道限定/了activerecord/LIB/active_record/validations.rb

belongs_to的是 供應商/軌道限定/了activerecord/LIB/active_record/associations.rb

ActiveRecord的是一個大的系統,包括許多混入,模塊等

注意,看到那裏被定義的方法,我用每種方法的,請參閱定義底部的「顯示源」鏈接。

]

29

類定義的主體是用於代碼就像任何其他的執行上下文。代碼在類的上下文中執行(意思是self是類對象,它是Class的一個實例)。您可以擁有局部變量和實例變量(它們將屬於類對象本身,而不屬於類的實例),您可以調用類對象響應的任何方法。代碼在類定義塊完成後運行。

在這種情況下,ActiveRecord :: Base定義了類方法validates_presence_ofbelongs_to

11

這些是類方法或「單例」方法。你應該熟悉的是attr_accessor。我們可以在測試類中實現類似的東西。

class Klass 
    def self.add_getter_and_setter(symbol) 
    module_eval "def #{symbol}; @#{symbol}; end" 
    module_eval "def #{symbol}=(val); @#{symbol} = val; end" 
    end 
end 

class Person < Klass 
    add_getter_and_setter :name 
    add_getter_and_setter :phone 
end 

person = Person.new 
person.name = 'John Smith' 
person.phone = '555-2344' 
person # returns <Person:0x28744 @name="John Smith", @phone="555-2344"> 

在上面的例子中,我們創建的類的方法與「高清self.add_getter_and_setter」,但這不是唯一的方法。

class Klass 
    class << self # opens the singleton class 
    def add_getter_and_setter(symbol) # note we dont specify self as it is already within the context of the singleton class 
     .. 
    end 
    end 
end 

使用擴展。 Module#extend是一個使用類方法擴展類的方法,同樣,Module#include方法也包含一個帶有實例方法的類。

class Klass 
    extend(Module.new do 
    def add_getter_and_setter(symbol) 
     .. 
    end 
    end) 
end 

如果克拉斯已經被定義,我們可以重新打開它來添加類方法

class Klass 
end 

def Klass.add_getter_and_setter(symbol) 
    .. 
end 

# or 

class << Klass 
    def add_getter_and_setter(symbol) 
    .. 
    end 
end 

那麼這些都是一些方法我知道如何,如果你看到這樣做,所以不同的語法只是實現其所有做同樣的事情。

注意:在rails中,我們都使用的通用類方法是'find'。它直接從Model類運行。

person = Person.find(1) # finds a person with id:1