2017-02-14 66 views
-2

我有一個關於Rails的ActiveRecord的問題。Rails ActiveRecord:何處定義方法?

例如我有一個Service模型,而Servicename作爲列。

這是app/model/service.rb

class Service < ActiveRecord::Base 

    def self.class_method 
    puts 'This is class method' 
    end 

    def instance_method 
    puts 'This is instance method' 
    end 
end 

然後,我可以做,

Service.class_method #=> 'This is class method' 

Service.find(1).instance_method #=> 'This is instance method' 

這很容易。但是,當我得到的ActiveRecord例如在陣列,例如

Service.where(id: [1,2,3]) 

,我需要像法,

Service.where(id: [1,2,3]).sample_method 

def sample_method 
    self.length 
end 

但如何以及在何處定義的Active Record陣列的方法?我想處理這個對象就像其他Service類或實例。

謝謝。

+0

更新第一款了。 –

回答

0

首先,where返回一個ActiveRecord :: Relation對象,而不是一個陣列。它的行爲類似於數組,但繼承了加載更多的方法來處理數據/構造用於查詢數據庫的SQL。

如果你想更多的功能添加到的ActiveRecord ::關係類,你可以做這樣的事情:

class ActiveRecord::Relation 
    def your_method 
    # do something 
    end 
end 

這將需要居住的地方有意義的,比如lib目錄或配置/初始化。

這應該允許你做這樣的事情

Service.where(id: [1,2,3]).your_method 

你可以做任何Ruby類類似的東西,像哈希,或Array類爲好。

然而,有幾乎總是一個更好的解決方案不是擴展/覆蓋的Rails/Ruby源類...

+0

啊我誤解了。是的,'哪裏'返回ActiveRecord :: Relation對象,而不是數組。所以最好的方法是繼承ActiveRecord :: Relation類並添加實例方法。謝謝。 –

+0

你可以這樣做 - 但一般來說,向ActiveRecord :: Relation類添加方法並不是最好的方法。我個人會創建一個單獨的類或模塊,並將Service.where(id:[1,2,3])的結果傳遞給它。然後,您可以在該類中執行您需要做的事情,而無需更改ActiveRecord :: Relation的行爲。這是更好的做法,因爲您的特定功能可以單獨進行測試,並且不會冒險改變應用程序其他區域中Relation類的庫存行爲。 – JayJay

0

你的方法,如get_countget_name有點毫無意義......爲什麼不只是做:

Service.count 

Service.find(1).name 

類的方法,如count,和實例方法,如name(即數據庫列名)都公共 - 所以你不需要定義你自己的getter方法。

至於你的第二個例子,你可以只是寫:

Service.where(id: [1,2,3]).map{ |s| s.name } 

或等價:

Service.where(id: [1,2,3]).map(&:name) 

但下面其實是更有效,因爲它是執行計算in SQL而不是紅寶石。 (如果你困惑什麼,我的意思是說,嘗試運行兩個版本,並比較產生什麼SQL,在日誌中):

Service.where(id: [1,2,3]).pluck(:name) 
+0

對不起,我只是想知道如何以及在哪裏定義Active Record Array實例的方法。爲了防止誤解,我修改了一下代碼。 –

+0

我的答案仍然保持不變......我只是把它寫成'Service.where(id:[1,2,3])。map(&:length)'。你*可以*也可以簡單地將其定義爲'def self.sample_method ....',但是在你的原始問題和更新問題中你都沒有提供一個合理的用例。 –

相關問題