2011-11-30 52 views
1

我正在創建一個gem,它在ActiveRecord類中創建類似before_update_filter的鉤子。 爲此,我必須創建一個模塊UpdateFilter,如下所示:如何動態地實現rails的ActiveRecord類的after_save鉤子

module UpdateFilter 
def before_update_filter(*args) 
    puts self #in class scope 
    self.set_callback(:save, :before, args[0].to_sym) 
end 
end 

而在intializers我做

ActiveRecord::Base.extend UpdateFilter 

確定。現在所有以上工作正常。但是,只有當實例的某些屬性發生更改時,我纔想要set_callbacks,並且我無法訪問before_update_filter方法中的屬性,因爲它在類範圍內。

作爲一個總結,我想實現hook like。我希望它能清除我想要做的事情。

before_update_filter :instance_mthod_name, :attr_prams => [:name, :rating] 

現在我該怎麼實現呢?

回答

2

這可能需要一些修改,但我認爲應該工作:

module UpdateFilter 
def before_update_filter(callback_method, options = {}) 
    puts self # class scope 
    self.set_callback :save, :before do 
     puts self # instance scope 
     # check if all of the listed attributes have changed 
     if options[:attr_params].map{ |attr| attribute_changed?(attr) }.all? 
     # call instance method 
     send callback_method 
     end 
    end 
end 
end 

根據傳遞給set_callbackdocs塊的當前對象的上下文中執行。所以我們可以訪問這個塊內的所有實例方法。我們檢查所有(用'any'或者其他一些條件替換它)列出的屬性已經改變,然後才調用所需的回調實例方法。