2011-02-17 45 views
2

在active_record/base.rb,module ActiveRecord方法,您可以看到這樣的代碼:瞭解代表和範圍的Rails中

delegate :find, :first, :last, :all, :destroy, :destroy_all, :exists?, :delete, 
      :delete_all, :update, :update_all, :to => :scoped 

讓我們first方法,所以我認爲first方法委託給scoped方法,然後scoped應從數據庫返回第一條記錄。但scoped只是匿名scope,目前的建設如何做它的工作?

與此同時,動態方法如何工作,如find_by_namefind_all_by_name_and_colour

謝謝

回答

2

開銷按照documentationdelegate

提供一個委託類的方法來 容易公開包含對象' 方法爲您自己的方法。通過一個或多個 方法(指定爲符號或 字符串),並通過目標 對象的名稱:到選項(也是 符號或字符串)

因此,這代表在列表中的方法scoped方法,它定義在ActiveRecord :: NamedScoped :: ClassMethods中,並且其中的returns an anonymous scope

至於爲什麼ActiveRecord會這樣做,所以我們可以繼續使用熟悉的方法,如find,而幕後AR實際上正在調用新穎的Arel方法。舉例來說,當你做

Post.find(37) 

什麼是真正得到執行是:

Post.where(primary_key.eq(37)) 
1

我會回答你的第二個問題。 find_by_name和find_all_by_what_you_want依靠ruby的寶貴method_missing。只要方法不存在,對象就會調用method_missing,您可以覆蓋它。例如,我可能想覆蓋method_missing,捕獲所有不存在的方法調用,檢查一些正則表達式,如果他們開始/結束/包含一些關鍵字等。

在你的例子中,我會覆蓋method_missing,檢查if它從查找開始,如果是,則分割''關鍵字以獲取他們屬性的一個數組,我想用它來查找。

這裏是一個很好的例子:http://technicalpickles.com/posts/using-method_missing-and-respond_to-to-create-dynamic-methods/

1

第一:「委託」委託給一個對象,而不是一個方法 - 所以「範圍」一定是有對象。

如果不檢查源代碼來驗證並且繼續使用ActiveRecord的工作知識,那麼我會假設「範圍」將是當前的AR實例,除非它在關聯代理上被調用。

因此:

User.first # "scope" will be User 

User.posts.first # "scope" will be the Post collection proxy 

@christianblais是問題#2是正確的,method_missing正在處理這些調用。此外,實際的Rails定義了第一個電話丟失的方法,以便後續調用它不招致method_missing