2013-01-16 34 views
1

可能重複:
What is the order of ActiveRecord callbacks and validations?何時執行了before_filter?

我來自Java的背景。有一件事我覺得很奇怪 in Rails是你可以設置回調函數就好像屬性就在這個類下面,比如before_filter

class SomeController < ActionController::Base 
    before_filter Proc.new {.....} 
end 

我真的不明白它是如何工作的。我找到了this post,它解釋了before_filter。我理解邏輯的流程,它只是一種方法。但我仍然不明白什麼時候會執行before_filter來設置回調鏈。

+0

''before_filter'不是由Ruby提供的,而是由Rails(特別是ActiveRecord)提供的。我編輯了你的問題來反映這一點。 –

+0

這些都是ActiveRecord回調 - 這不是一回事。 –

+1

堅果殼:加載類時運行'before_filter'。 –

回答

11

before_filter不是紅寶石特徵,它是由Ruby on Rails的(web框架),可在控制器中使用在控制器中執行的任何動作之前執行的一段代碼提供了一種類方法。

那麼,Ruby on Rails如何做到這一點?

當你定義一個類在Ruby中,你實際上執行的代碼,試試這個在IRB:

class Hello 
    puts "defining hello..." 

    def greet 
    puts "Hello there" 
    end 
end 

你會看到「定義你好......」被印在終端,當你定義班上。你沒有實例化任何對象,你只是定義了一個類,但是你可以在定義類的過程中執行任何代碼。

你知道你可以定義「類方法」和「實例方法」,這有什麼有趣的是,你可以打電話給你的類的方法,而你仍然定義類:

class MyClass 
    def self.add_component(component) 
    # Here @@components is a class variable 
    @@components ||= []  # set the variable to an empty array if not already set. 
    @@components << component # add the component to the array 
    end 

    add_component(:mouse) 
    add_component(:keyboard) 
    add_component(:screen) 

    def components 
    @@components # The @@ gets you the class variable 
    end 
end 

MyClass.new.components 
=> [:mouse, :keyboard, :screen] 

def self.add_component定義一個類方法,你可以調用,同時仍然定義你的班級。在這個例子中,add_component將一個鍵盤添加到類變量的列表中,並且實例方法(在該類的一個實例上調用)訪問此類變量。類方法可以在父類中定義,它的工作原理也是一樣的。這個例子可能有點奇怪。

讓我們來做另一個例子。

class RubyOnSlugsController 
    def self.before_filter(callback) 
    @@callbacks ||= [] 
    @@callbacks << callback 
    end 

    def execute_callbacks 
    @@callbacks.each { |callback| callback.call() } 
    return "callbacks executed" 
    end 
end 

class MyController < RubyOnSlugsController 
    before_filter Proc.new { puts "I'm a before filter!" } 
    before_filter Proc.new { puts "2 + 2 is #{2 + 2}" } 
end 

controller = MyController.new 
controller.execute_callbacks 

將輸出:

I'm a before filter! 
2 + 2 is 4 
=> "callbacks executed" 

Ruby on Rails的做類似(但相當多複雜的)與before_filter東西,它可以確保你用它定義所有回調您的正常控制器方法之前調用。

我希望這能爲你解決一些問題。

+0

非常好的解釋:)只是幾分鐘前,我誤解'before_filter'作爲實例方法...我從來沒有想過我可以在定義類時調用類方法:)它看起來非常神奇。 – code4j

1

當你的控制器文件被加載時(即當你的服務器啓動時),before_filter方法本身就會運行。這意味着只要定義了類,就會設置回調鏈。

至於它設置的回調,控制器有一個process方法,該方法取一個動作的名字(比如「index」),並調用process_action中的相應動作方法。回調模塊用runs the callback的實現覆蓋了這個方法。

+0

我從來沒有通過我可以在Ruby類中執行Ruby代碼.. – code4j